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