| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/cert/x509_certificate.h" | 5 #include "net/cert/x509_certificate.h" |
| 6 | 6 |
| 7 #include <cert.h> | 7 #include <cert.h> |
| 8 #include <cryptohi.h> | 8 #include <cryptohi.h> |
| 9 #include <keyhi.h> | 9 #include <keyhi.h> |
| 10 #include <nss.h> | 10 #include <nss.h> |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); | 36 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); |
| 37 | 37 |
| 38 serial_number_ = x509_util::ParseSerialNumber(cert_handle_); | 38 serial_number_ = x509_util::ParseSerialNumber(cert_handle_); |
| 39 } | 39 } |
| 40 | 40 |
| 41 // static | 41 // static |
| 42 X509Certificate* X509Certificate::CreateFromBytesWithNickname( | 42 X509Certificate* X509Certificate::CreateFromBytesWithNickname( |
| 43 const char* data, | 43 const char* data, |
| 44 int length, | 44 int length, |
| 45 const char* nickname) { | 45 const char* nickname) { |
| 46 OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data, | 46 OSCertHandle cert_handle = |
| 47 length, | 47 CreateOSCertHandleFromBytesWithNickname(data, length, nickname); |
| 48 nickname); | |
| 49 if (!cert_handle) | 48 if (!cert_handle) |
| 50 return NULL; | 49 return NULL; |
| 51 | 50 |
| 52 X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles()); | 51 X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles()); |
| 53 FreeOSCertHandle(cert_handle); | 52 FreeOSCertHandle(cert_handle); |
| 54 | 53 |
| 55 if (nickname) | 54 if (nickname) |
| 56 cert->default_nickname_ = nickname; | 55 cert->default_nickname_ = nickname; |
| 57 | 56 |
| 58 return cert; | 57 return cert; |
| 59 } | 58 } |
| 60 | 59 |
| 61 std::string X509Certificate::GetDefaultNickname(CertType type) const { | 60 std::string X509Certificate::GetDefaultNickname(CertType type) const { |
| 62 if (!default_nickname_.empty()) | 61 if (!default_nickname_.empty()) |
| 63 return default_nickname_; | 62 return default_nickname_; |
| 64 | 63 |
| 65 std::string result; | 64 std::string result; |
| 66 if (type == USER_CERT && cert_handle_->slot) { | 65 if (type == USER_CERT && cert_handle_->slot) { |
| 67 // Find the private key for this certificate and see if it has a | 66 // Find the private key for this certificate and see if it has a |
| 68 // nickname. If there is a private key, and it has a nickname, then | 67 // nickname. If there is a private key, and it has a nickname, then |
| 69 // return that nickname. | 68 // return that nickname. |
| 70 SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert( | 69 SECKEYPrivateKey* private_key = |
| 71 cert_handle_->slot, | 70 PK11_FindPrivateKeyFromCert(cert_handle_->slot, |
| 72 cert_handle_, | 71 cert_handle_, |
| 73 NULL); // wincx | 72 NULL); // wincx |
| 74 if (private_key) { | 73 if (private_key) { |
| 75 char* private_key_nickname = PK11_GetPrivateKeyNickname(private_key); | 74 char* private_key_nickname = PK11_GetPrivateKeyNickname(private_key); |
| 76 if (private_key_nickname) { | 75 if (private_key_nickname) { |
| 77 result = private_key_nickname; | 76 result = private_key_nickname; |
| 78 PORT_Free(private_key_nickname); | 77 PORT_Free(private_key_nickname); |
| 79 SECKEY_DestroyPrivateKey(private_key); | 78 SECKEY_DestroyPrivateKey(private_key); |
| 80 return result; | 79 return result; |
| 81 } | 80 } |
| 82 SECKEY_DestroyPrivateKey(private_key); | 81 SECKEY_DestroyPrivateKey(private_key); |
| 83 } | 82 } |
| 84 } | 83 } |
| 85 | 84 |
| 86 switch (type) { | 85 switch (type) { |
| 87 case CA_CERT: { | 86 case CA_CERT: { |
| 88 char* nickname = CERT_MakeCANickname(cert_handle_); | 87 char* nickname = CERT_MakeCANickname(cert_handle_); |
| 89 result = nickname; | 88 result = nickname; |
| 90 PORT_Free(nickname); | 89 PORT_Free(nickname); |
| 91 break; | 90 break; |
| 92 } | 91 } |
| 93 case USER_CERT: { | 92 case USER_CERT: { |
| 94 std::string subject_name = subject_.GetDisplayName(); | 93 std::string subject_name = subject_.GetDisplayName(); |
| 95 if (subject_name.empty()) { | 94 if (subject_name.empty()) { |
| 96 const char* email = CERT_GetFirstEmailAddress(cert_handle_); | 95 const char* email = CERT_GetFirstEmailAddress(cert_handle_); |
| 97 if (email) | 96 if (email) |
| 98 subject_name = email; | 97 subject_name = email; |
| 99 } | 98 } |
| 100 // TODO(gspencer): Internationalize this. It's wrong to assume English | 99 // TODO(gspencer): Internationalize this. It's wrong to assume English |
| 101 // here. | 100 // here. |
| 102 result = base::StringPrintf("%s's %s ID", subject_name.c_str(), | 101 result = base::StringPrintf( |
| 103 issuer_.GetDisplayName().c_str()); | 102 "%s's %s ID", subject_name.c_str(), issuer_.GetDisplayName().c_str()); |
| 104 break; | 103 break; |
| 105 } | 104 } |
| 106 case SERVER_CERT: | 105 case SERVER_CERT: |
| 107 result = subject_.GetDisplayName(); | 106 result = subject_.GetDisplayName(); |
| 108 break; | 107 break; |
| 109 case OTHER_CERT: | 108 case OTHER_CERT: |
| 110 default: | 109 default: |
| 111 break; | 110 break; |
| 112 } | 111 } |
| 113 return result; | 112 return result; |
| 114 } | 113 } |
| 115 | 114 |
| 116 void X509Certificate::GetSubjectAltName( | 115 void X509Certificate::GetSubjectAltName( |
| 117 std::vector<std::string>* dns_names, | 116 std::vector<std::string>* dns_names, |
| 118 std::vector<std::string>* ip_addrs) const { | 117 std::vector<std::string>* ip_addrs) const { |
| 119 x509_util::GetSubjectAltName(cert_handle_, dns_names, ip_addrs); | 118 x509_util::GetSubjectAltName(cert_handle_, dns_names, ip_addrs); |
| 120 } | 119 } |
| 121 | 120 |
| 122 bool X509Certificate::IsIssuedByEncoded( | 121 bool X509Certificate::IsIssuedByEncoded( |
| 123 const std::vector<std::string>& valid_issuers) { | 122 const std::vector<std::string>& valid_issuers) { |
| 124 // Get certificate chain as scoped list of CERTCertificate objects. | 123 // Get certificate chain as scoped list of CERTCertificate objects. |
| 125 std::vector<CERTCertificate*> cert_chain; | 124 std::vector<CERTCertificate*> cert_chain; |
| 126 cert_chain.push_back(cert_handle_); | 125 cert_chain.push_back(cert_handle_); |
| 127 for (size_t n = 0; n < intermediate_ca_certs_.size(); ++n) { | 126 for (size_t n = 0; n < intermediate_ca_certs_.size(); ++n) { |
| 128 cert_chain.push_back(intermediate_ca_certs_[n]); | 127 cert_chain.push_back(intermediate_ca_certs_[n]); |
| 129 } | 128 } |
| 130 // Convert encoded issuers to scoped CERTName* list. | 129 // Convert encoded issuers to scoped CERTName* list. |
| 131 std::vector<CERTName*> issuers; | 130 std::vector<CERTName*> issuers; |
| 132 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); | 131 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); |
| 133 if (!x509_util::GetIssuersFromEncodedList(valid_issuers, | 132 if (!x509_util::GetIssuersFromEncodedList( |
| 134 arena.get(), | 133 valid_issuers, arena.get(), &issuers)) { |
| 135 &issuers)) { | |
| 136 return false; | 134 return false; |
| 137 } | 135 } |
| 138 return x509_util::IsCertificateIssuedBy(cert_chain, issuers); | 136 return x509_util::IsCertificateIssuedBy(cert_chain, issuers); |
| 139 } | 137 } |
| 140 | 138 |
| 141 // static | 139 // static |
| 142 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, | 140 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, |
| 143 std::string* encoded) { | 141 std::string* encoded) { |
| 144 if (!cert_handle->derCert.len) | 142 if (!cert_handle->derCert.len) |
| 145 return false; | 143 return false; |
| 146 encoded->assign(reinterpret_cast<char*>(cert_handle->derCert.data), | 144 encoded->assign(reinterpret_cast<char*>(cert_handle->derCert.data), |
| 147 cert_handle->derCert.len); | 145 cert_handle->derCert.len); |
| 148 return true; | 146 return true; |
| 149 } | 147 } |
| 150 | 148 |
| 151 // static | 149 // static |
| 152 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, | 150 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, |
| 153 X509Certificate::OSCertHandle b) { | 151 X509Certificate::OSCertHandle b) { |
| 154 DCHECK(a && b); | 152 DCHECK(a && b); |
| 155 if (a == b) | 153 if (a == b) |
| 156 return true; | 154 return true; |
| 157 return a->derCert.len == b->derCert.len && | 155 return a->derCert.len == b->derCert.len && |
| 158 memcmp(a->derCert.data, b->derCert.data, a->derCert.len) == 0; | 156 memcmp(a->derCert.data, b->derCert.data, a->derCert.len) == 0; |
| 159 } | 157 } |
| 160 | 158 |
| 161 // static | 159 // static |
| 162 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( | 160 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( |
| 163 const char* data, int length) { | 161 const char* data, |
| 162 int length) { |
| 164 return CreateOSCertHandleFromBytesWithNickname(data, length, NULL); | 163 return CreateOSCertHandleFromBytesWithNickname(data, length, NULL); |
| 165 } | 164 } |
| 166 | 165 |
| 167 // static | 166 // static |
| 168 X509Certificate::OSCertHandle | 167 X509Certificate::OSCertHandle |
| 169 X509Certificate::CreateOSCertHandleFromBytesWithNickname( | 168 X509Certificate::CreateOSCertHandleFromBytesWithNickname(const char* data, |
| 170 const char* data, | 169 int length, |
| 171 int length, | 170 const char* nickname) { |
| 172 const char* nickname) { | |
| 173 if (length < 0) | 171 if (length < 0) |
| 174 return NULL; | 172 return NULL; |
| 175 | 173 |
| 176 crypto::EnsureNSSInit(); | 174 crypto::EnsureNSSInit(); |
| 177 | 175 |
| 178 if (!NSS_IsInitialized()) | 176 if (!NSS_IsInitialized()) |
| 179 return NULL; | 177 return NULL; |
| 180 | 178 |
| 181 SECItem der_cert; | 179 SECItem der_cert; |
| 182 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data)); | 180 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data)); |
| 183 der_cert.len = length; | 181 der_cert.len = length; |
| 184 der_cert.type = siDERCertBuffer; | 182 der_cert.type = siDERCertBuffer; |
| 185 | 183 |
| 186 // Parse into a certificate structure. | 184 // Parse into a certificate structure. |
| 187 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, | 185 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), |
| 186 &der_cert, |
| 188 const_cast<char*>(nickname), | 187 const_cast<char*>(nickname), |
| 189 PR_FALSE, PR_TRUE); | 188 PR_FALSE, |
| 189 PR_TRUE); |
| 190 } | 190 } |
| 191 | 191 |
| 192 // static | 192 // static |
| 193 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( | 193 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( |
| 194 const char* data, | 194 const char* data, |
| 195 int length, | 195 int length, |
| 196 Format format) { | 196 Format format) { |
| 197 return x509_util::CreateOSCertHandlesFromBytes(data, length, format); | 197 return x509_util::CreateOSCertHandlesFromBytes(data, length, format); |
| 198 } | 198 } |
| 199 | 199 |
| 200 // static | 200 // static |
| 201 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 201 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
| 202 OSCertHandle cert_handle) { | 202 OSCertHandle cert_handle) { |
| 203 return CERT_DupCertificate(cert_handle); | 203 return CERT_DupCertificate(cert_handle); |
| 204 } | 204 } |
| 205 | 205 |
| 206 // static | 206 // static |
| 207 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { | 207 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
| 208 CERT_DestroyCertificate(cert_handle); | 208 CERT_DestroyCertificate(cert_handle); |
| 209 } | 209 } |
| 210 | 210 |
| 211 // static | 211 // static |
| 212 SHA1HashValue X509Certificate::CalculateFingerprint( | 212 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) { |
| 213 OSCertHandle cert) { | |
| 214 SHA1HashValue sha1; | 213 SHA1HashValue sha1; |
| 215 memset(sha1.data, 0, sizeof(sha1.data)); | 214 memset(sha1.data, 0, sizeof(sha1.data)); |
| 216 | 215 |
| 217 DCHECK(NULL != cert->derCert.data); | 216 DCHECK(NULL != cert->derCert.data); |
| 218 DCHECK_NE(0U, cert->derCert.len); | 217 DCHECK_NE(0U, cert->derCert.len); |
| 219 | 218 |
| 220 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data, | 219 SECStatus rv = HASH_HashBuf( |
| 221 cert->derCert.data, cert->derCert.len); | 220 HASH_AlgSHA1, sha1.data, cert->derCert.data, cert->derCert.len); |
| 222 DCHECK_EQ(SECSuccess, rv); | 221 DCHECK_EQ(SECSuccess, rv); |
| 223 | 222 |
| 224 return sha1; | 223 return sha1; |
| 225 } | 224 } |
| 226 | 225 |
| 227 // static | 226 // static |
| 228 SHA1HashValue X509Certificate::CalculateCAFingerprint( | 227 SHA1HashValue X509Certificate::CalculateCAFingerprint( |
| 229 const OSCertHandles& intermediates) { | 228 const OSCertHandles& intermediates) { |
| 230 SHA1HashValue sha1; | 229 SHA1HashValue sha1; |
| 231 memset(sha1.data, 0, sizeof(sha1.data)); | 230 memset(sha1.data, 0, sizeof(sha1.data)); |
| 232 | 231 |
| 233 HASHContext* sha1_ctx = HASH_Create(HASH_AlgSHA1); | 232 HASHContext* sha1_ctx = HASH_Create(HASH_AlgSHA1); |
| 234 if (!sha1_ctx) | 233 if (!sha1_ctx) |
| 235 return sha1; | 234 return sha1; |
| 236 HASH_Begin(sha1_ctx); | 235 HASH_Begin(sha1_ctx); |
| 237 for (size_t i = 0; i < intermediates.size(); ++i) { | 236 for (size_t i = 0; i < intermediates.size(); ++i) { |
| 238 CERTCertificate* ca_cert = intermediates[i]; | 237 CERTCertificate* ca_cert = intermediates[i]; |
| 239 HASH_Update(sha1_ctx, ca_cert->derCert.data, ca_cert->derCert.len); | 238 HASH_Update(sha1_ctx, ca_cert->derCert.data, ca_cert->derCert.len); |
| 240 } | 239 } |
| 241 unsigned int result_len; | 240 unsigned int result_len; |
| 242 HASH_End(sha1_ctx, sha1.data, &result_len, HASH_ResultLenContext(sha1_ctx)); | 241 HASH_End(sha1_ctx, sha1.data, &result_len, HASH_ResultLenContext(sha1_ctx)); |
| 243 HASH_Destroy(sha1_ctx); | 242 HASH_Destroy(sha1_ctx); |
| 244 | 243 |
| 245 return sha1; | 244 return sha1; |
| 246 } | 245 } |
| 247 | 246 |
| 248 // static | 247 // static |
| 249 X509Certificate::OSCertHandle | 248 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle( |
| 250 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { | 249 PickleIterator* pickle_iter) { |
| 251 return x509_util::ReadOSCertHandleFromPickle(pickle_iter); | 250 return x509_util::ReadOSCertHandleFromPickle(pickle_iter); |
| 252 } | 251 } |
| 253 | 252 |
| 254 // static | 253 // static |
| 255 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, | 254 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, |
| 256 Pickle* pickle) { | 255 Pickle* pickle) { |
| 257 return pickle->WriteData( | 256 return pickle->WriteData( |
| 258 reinterpret_cast<const char*>(cert_handle->derCert.data), | 257 reinterpret_cast<const char*>(cert_handle->derCert.data), |
| 259 cert_handle->derCert.len); | 258 cert_handle->derCert.len); |
| 260 } | 259 } |
| 261 | 260 |
| 262 // static | 261 // static |
| 263 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, | 262 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, |
| 264 size_t* size_bits, | 263 size_t* size_bits, |
| 265 PublicKeyType* type) { | 264 PublicKeyType* type) { |
| 266 x509_util::GetPublicKeyInfo(cert_handle, size_bits, type); | 265 x509_util::GetPublicKeyInfo(cert_handle, size_bits, type); |
| 267 } | 266 } |
| 268 | 267 |
| 269 } // namespace net | 268 } // namespace net |
| OLD | NEW |