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