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.
5 #include "net/cert/x509_util_ios.h"
8 #include <CommonCrypto/CommonDigest.h>
12 #include "base/mac/scoped_cftyperef.h"
13 #include "crypto/nss_util.h"
14 #include "net/cert/x509_certificate.h"
15 #include "net/cert/x509_util_nss.h"
17 using base::ScopedCFTypeRef;
20 namespace x509_util_ios {
24 // Creates an NSS certificate handle from |data|, which is |length| bytes in
26 CERTCertificate* CreateNSSCertHandleFromBytes(const char* data,
31 crypto::EnsureNSSInit();
33 if (!NSS_IsInitialized())
37 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
38 der_cert.len = length;
39 der_cert.type = siDERCertBuffer;
41 // Parse into a certificate structure.
42 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, NULL,
48 CERTCertificate* CreateNSSCertHandleFromOSHandle(
49 SecCertificateRef cert_handle) {
50 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle));
51 return CreateNSSCertHandleFromBytes(
52 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)),
53 CFDataGetLength(cert_data));
56 SecCertificateRef CreateOSCertHandleFromNSSHandle(
57 CERTCertificate* nss_cert_handle) {
58 return X509Certificate::CreateOSCertHandleFromBytes(
59 reinterpret_cast<const char*>(nss_cert_handle->derCert.data),
60 nss_cert_handle->derCert.len);
63 X509Certificate* CreateCertFromNSSHandles(
64 CERTCertificate* cert_handle,
65 const std::vector<CERTCertificate*>& intermediates) {
66 ScopedCFTypeRef<SecCertificateRef> os_server_cert(
67 CreateOSCertHandleFromNSSHandle(cert_handle));
70 std::vector<SecCertificateRef> os_intermediates;
71 for (size_t i = 0; i < intermediates.size(); ++i) {
72 SecCertificateRef intermediate =
73 CreateOSCertHandleFromNSSHandle(intermediates[i]);
76 os_intermediates.push_back(intermediate);
79 X509Certificate* cert = NULL;
80 if (intermediates.size() == os_intermediates.size()) {
81 cert = X509Certificate::CreateFromHandle(os_server_cert,
85 for (size_t i = 0; i < os_intermediates.size(); ++i)
86 CFRelease(os_intermediates[i]);
90 SHA1HashValue CalculateFingerprintNSS(CERTCertificate* cert) {
91 DCHECK(cert->derCert.data);
92 DCHECK_NE(0U, cert->derCert.len);
94 memset(sha1.data, 0, sizeof(sha1.data));
95 CC_SHA1(cert->derCert.data, cert->derCert.len, sha1.data);
99 // NSSCertificate implementation.
101 NSSCertificate::NSSCertificate(SecCertificateRef cert_handle) {
102 nss_cert_handle_ = CreateNSSCertHandleFromOSHandle(cert_handle);
103 DLOG_IF(INFO, cert_handle && !nss_cert_handle_)
104 << "Could not convert SecCertificateRef to CERTCertificate*";
107 NSSCertificate::~NSSCertificate() {
108 CERT_DestroyCertificate(nss_cert_handle_);
111 CERTCertificate* NSSCertificate::cert_handle() const {
112 return nss_cert_handle_;
115 // NSSCertChain implementation
117 NSSCertChain::NSSCertChain(X509Certificate* certificate) {
119 certs_.push_back(CreateNSSCertHandleFromOSHandle(
120 certificate->os_cert_handle()));
121 const X509Certificate::OSCertHandles& cert_intermediates =
122 certificate->GetIntermediateCertificates();
123 for (size_t i = 0; i < cert_intermediates.size(); ++i)
124 certs_.push_back(CreateNSSCertHandleFromOSHandle(cert_intermediates[i]));
127 NSSCertChain::~NSSCertChain() {
128 for (size_t i = 0; i < certs_.size(); ++i)
129 CERT_DestroyCertificate(certs_[i]);
132 CERTCertificate* NSSCertChain::cert_handle() const {
133 return certs_.empty() ? NULL : certs_.front();
136 const std::vector<CERTCertificate*>& NSSCertChain::cert_chain() const {
140 } // namespace x509_util_ios