Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: net/base/x509_certificate_nss.cc

Issue 27033: Implement X509Certificate::Persist. This fixes gmail on linux. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | net/base/x509_certificate_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/x509_certificate.h" 5 #include "net/base/x509_certificate.h"
6 6
7 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 7 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
8 // until NSS 3.12.2 comes out and we update to it. 8 // until NSS 3.12.2 comes out and we update to it.
9 #define Lock FOO_NSS_Lock 9 #define Lock FOO_NSS_Lock
10 #include <cert.h> 10 #include <cert.h>
11 #include <prtime.h> 11 #include <prtime.h>
12 #include <secder.h> 12 #include <secder.h>
13 #include <sechash.h> 13 #include <sechash.h>
14 #undef Lock 14 #undef Lock
15 15
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/pickle.h"
17 #include "base/time.h" 18 #include "base/time.h"
18 #include "base/nss_init.h" 19 #include "base/nss_init.h"
19 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
20 21
21 namespace net { 22 namespace net {
22 23
23 namespace { 24 namespace {
24 25
25 // TODO(port): Implement this more simply, and put it in the right place 26 // TODO(port): Implement this more simply, and put it in the right place
26 base::Time PRTimeToBaseTime(PRTime prtime) { 27 base::Time PRTimeToBaseTime(PRTime prtime) {
27 PRExplodedTime prxtime; 28 PRExplodedTime prxtime;
28 PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime); 29 PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime);
29 30
30 base::Time::Exploded exploded; 31 base::Time::Exploded exploded;
31 exploded.year = prxtime.tm_year; 32 exploded.year = prxtime.tm_year;
32 exploded.month = prxtime.tm_month + 1; 33 exploded.month = prxtime.tm_month + 1;
33 exploded.day_of_week = prxtime.tm_wday; 34 exploded.day_of_week = prxtime.tm_wday;
34 exploded.day_of_month = prxtime.tm_mday; 35 exploded.day_of_month = prxtime.tm_mday;
35 exploded.hour = prxtime.tm_hour; 36 exploded.hour = prxtime.tm_hour;
36 exploded.minute = prxtime.tm_min; 37 exploded.minute = prxtime.tm_min;
37 exploded.second = prxtime.tm_sec; 38 exploded.second = prxtime.tm_sec;
38 exploded.millisecond = prxtime.tm_usec / 1000; 39 exploded.millisecond = prxtime.tm_usec / 1000;
39 40
40 return base::Time::FromUTCExploded(exploded); 41 return base::Time::FromUTCExploded(exploded);
41 } 42 }
42 43
43 void ParsePrincipal(SECItem* der_name, 44 void ParsePrincipal(SECItem* der_name,
44 X509Certificate::Principal* principal) { 45 X509Certificate::Principal* principal) {
45 46
46 CERTName name; 47 CERTName name;
47 PRArenaPool* arena = NULL; 48 PRArenaPool* arena = NULL;
48 49
49 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 50 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
50 DCHECK(arena != NULL); 51 DCHECK(arena != NULL);
51 if (arena == NULL) 52 if (arena == NULL)
52 return; 53 return;
53 54
54 // TODO(dkegel): is CERT_NameTemplate what we always want here? 55 // TODO(dkegel): is CERT_NameTemplate what we always want here?
55 SECStatus rv; 56 SECStatus rv;
56 rv = SEC_QuickDERDecodeItem(arena, &name, CERT_NameTemplate, der_name); 57 rv = SEC_QuickDERDecodeItem(arena, &name, CERT_NameTemplate, der_name);
57 DCHECK(rv == SECSuccess); 58 DCHECK(rv == SECSuccess);
58 if ( rv != SECSuccess ) { 59 if ( rv != SECSuccess ) {
59 PORT_FreeArena(arena, PR_FALSE); 60 PORT_FreeArena(arena, PR_FALSE);
60 return; 61 return;
61 } 62 }
62 63
63 std::vector<std::string> common_names, locality_names, state_names, 64 std::vector<std::string> common_names, locality_names, state_names,
64 country_names; 65 country_names;
65 66
66 // TODO(jcampan): add business_category and serial_number. 67 // TODO(jcampan): add business_category and serial_number.
67 static const SECOidTag kOIDs[] = { 68 static const SECOidTag kOIDs[] = {
68 SEC_OID_AVA_COMMON_NAME, 69 SEC_OID_AVA_COMMON_NAME,
69 SEC_OID_AVA_LOCALITY, 70 SEC_OID_AVA_LOCALITY,
70 SEC_OID_AVA_STATE_OR_PROVINCE, 71 SEC_OID_AVA_STATE_OR_PROVINCE,
71 SEC_OID_AVA_COUNTRY_NAME, 72 SEC_OID_AVA_COUNTRY_NAME,
72 SEC_OID_AVA_STREET_ADDRESS, 73 SEC_OID_AVA_STREET_ADDRESS,
73 SEC_OID_AVA_ORGANIZATION_NAME, 74 SEC_OID_AVA_ORGANIZATION_NAME,
74 SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, 75 SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
75 SEC_OID_AVA_DC }; 76 SEC_OID_AVA_DC };
76 77
77 std::vector<std::string>* values[] = { 78 std::vector<std::string>* values[] = {
78 &common_names, &locality_names, 79 &common_names, &locality_names,
79 &state_names, &country_names, 80 &state_names, &country_names,
80 &principal->street_addresses, 81 &principal->street_addresses,
81 &principal->organization_names, 82 &principal->organization_names,
82 &principal->organization_unit_names, 83 &principal->organization_unit_names,
83 &principal->domain_components }; 84 &principal->domain_components };
84 DCHECK(arraysize(kOIDs) == arraysize(values)); 85 DCHECK(arraysize(kOIDs) == arraysize(values));
85 86
86 CERTRDN** rdns = name.rdns; 87 CERTRDN** rdns = name.rdns;
87 for (size_t rdn = 0; rdns[rdn]; ++rdn) { 88 for (size_t rdn = 0; rdns[rdn]; ++rdn) {
88 CERTAVA** avas = rdns[rdn]->avas; 89 CERTAVA** avas = rdns[rdn]->avas;
89 for (size_t pair = 0; avas[pair] != 0; ++pair) { 90 for (size_t pair = 0; avas[pair] != 0; ++pair) {
90 SECOidTag tag = CERT_GetAVATag(avas[pair]); 91 SECOidTag tag = CERT_GetAVATag(avas[pair]);
91 for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { 92 for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
92 if (kOIDs[oid] == tag) { 93 if (kOIDs[oid] == tag) {
93 SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value); 94 SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
94 if (!decode_item) 95 if (!decode_item)
95 break; 96 break;
96 std::string value(reinterpret_cast<char*>(decode_item->data), 97 std::string value(reinterpret_cast<char*>(decode_item->data),
97 decode_item->len); 98 decode_item->len);
98 values[oid]->push_back(value); 99 values[oid]->push_back(value);
99 SECITEM_FreeItem(decode_item, PR_TRUE); 100 SECITEM_FreeItem(decode_item, PR_TRUE);
100 break; 101 break;
101 } 102 }
102 } 103 }
103 } 104 }
104 } 105 }
105 106
106 // We don't expect to have more than one CN, L, S, and C. 107 // We don't expect to have more than one CN, L, S, and C.
(...skipping 14 matching lines...) Expand all
121 PRTime prtime; 122 PRTime prtime;
122 SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date); 123 SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
123 DCHECK(rv == SECSuccess); 124 DCHECK(rv == SECSuccess);
124 *result = PRTimeToBaseTime(prtime); 125 *result = PRTimeToBaseTime(prtime);
125 } 126 }
126 127
127 void GetCertSubjectAltNamesOfType(X509Certificate::OSCertHandle cert_handle, 128 void GetCertSubjectAltNamesOfType(X509Certificate::OSCertHandle cert_handle,
128 CERTGeneralNameType name_type, 129 CERTGeneralNameType name_type,
129 std::vector<std::string>* result) { 130 std::vector<std::string>* result) {
130 131
131 SECItem alt_name; 132 SECItem alt_name;
132 SECStatus rv = CERT_FindCertExtension(cert_handle, 133 SECStatus rv = CERT_FindCertExtension(cert_handle,
133 SEC_OID_X509_SUBJECT_ALT_NAME, &alt_name); 134 SEC_OID_X509_SUBJECT_ALT_NAME, &alt_name);
134 if (rv != SECSuccess) 135 if (rv != SECSuccess)
135 return; 136 return;
136 137
137 PRArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 138 PRArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
138 DCHECK(arena != NULL); 139 DCHECK(arena != NULL);
139 140
140 CERTGeneralName* alt_name_list; 141 CERTGeneralName* alt_name_list;
141 alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name); 142 alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);
(...skipping 19 matching lines...) Expand all
161 } 162 }
162 163
163 } // namespace 164 } // namespace
164 165
165 void X509Certificate::Initialize() { 166 void X509Certificate::Initialize() {
166 ParsePrincipal(&cert_handle_->derSubject, &subject_); 167 ParsePrincipal(&cert_handle_->derSubject, &subject_);
167 ParsePrincipal(&cert_handle_->derIssuer, &issuer_); 168 ParsePrincipal(&cert_handle_->derIssuer, &issuer_);
168 169
169 ParseDate(&cert_handle_->validity.notBefore, &valid_start_); 170 ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
170 ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_); 171 ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);
171 172
172 fingerprint_ = CalculateFingerprint(cert_handle_); 173 fingerprint_ = CalculateFingerprint(cert_handle_);
173 174
174 // Store the certificate in the cache in case we need it later. 175 // Store the certificate in the cache in case we need it later.
175 X509Certificate::Cache::GetInstance()->Insert(this); 176 X509Certificate::Cache::GetInstance()->Insert(this);
176 } 177 }
177 178
178 // static 179 // static
179 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, 180 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
180 void** pickle_iter) { 181 void** pickle_iter) {
181 NOTIMPLEMENTED(); 182 const char* data;
182 return NULL; 183 int length;
184 if (!pickle.ReadData(pickle_iter, &data, &length))
185 return NULL;
186
187 return CreateFromBytes(data, length);
183 } 188 }
184 189
185 void X509Certificate::Persist(Pickle* pickle) { 190 void X509Certificate::Persist(Pickle* pickle) {
186 // TODO(port): implement. 191 pickle->WriteData(reinterpret_cast<const char*>(cert_handle_->derCert.data),
187 192 cert_handle_->derCert.len);
188 // Calling NOTIMPLEMENTED here breaks webkit tests.
189 //NOTIMPLEMENTED();
190 } 193 }
191 194
192 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { 195 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
193 dns_names->clear(); 196 dns_names->clear();
194 197
195 // Compare with CERT_VerifyCertName(). 198 // Compare with CERT_VerifyCertName().
196 GetCertSubjectAltNamesOfType(cert_handle_, certDNSName, dns_names); 199 GetCertSubjectAltNamesOfType(cert_handle_, certDNSName, dns_names);
197 200
198 // TODO(port): suppress nss's support of the obsolete extension 201 // TODO(port): suppress nss's support of the obsolete extension
199 // SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME 202 // SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME
200 // by providing our own authCertificate callback. 203 // by providing our own authCertificate callback.
201 204
202 if (dns_names->empty()) 205 if (dns_names->empty())
203 dns_names->push_back(subject_.common_name); 206 dns_names->push_back(subject_.common_name);
204 } 207 }
205 208
206 bool X509Certificate::HasExpired() const { 209 bool X509Certificate::HasExpired() const {
207 NOTIMPLEMENTED(); 210 NOTIMPLEMENTED();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 243
241 DCHECK(NULL != cert->derCert.data); 244 DCHECK(NULL != cert->derCert.data);
242 DCHECK(0 != cert->derCert.len); 245 DCHECK(0 != cert->derCert.len);
243 246
244 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data, 247 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data,
245 cert->derCert.data, cert->derCert.len); 248 cert->derCert.data, cert->derCert.len);
246 DCHECK(rv == SECSuccess); 249 DCHECK(rv == SECSuccess);
247 250
248 return sha1; 251 return sha1;
249 } 252 }
250 253
251 } // namespace net 254 } // namespace net
252 255
OLDNEW
« no previous file with comments | « no previous file | net/base/x509_certificate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698