- add sources.
[platform/framework/web/crosswalk.git] / src / net / cert / x509_util_ios.cc
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_util_ios.h"
6
7 #include <cert.h>
8 #include <CommonCrypto/CommonDigest.h>
9 #include <nss.h>
10 #include <prtypes.h>
11
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"
16
17 using base::ScopedCFTypeRef;
18
19 namespace net {
20 namespace x509_util_ios {
21
22 namespace {
23
24 // Creates an NSS certificate handle from |data|, which is |length| bytes in
25 // size.
26 CERTCertificate* CreateNSSCertHandleFromBytes(const char* data,
27                                               int length) {
28   if (length < 0)
29     return NULL;
30
31   crypto::EnsureNSSInit();
32
33   if (!NSS_IsInitialized())
34     return NULL;
35
36   SECItem der_cert;
37   der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
38   der_cert.len  = length;
39   der_cert.type = siDERCertBuffer;
40
41   // Parse into a certificate structure.
42   return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, NULL,
43                                  PR_FALSE, PR_TRUE);
44 }
45
46 }  // namespace
47
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));
54 }
55
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);
61 }
62
63 X509Certificate* CreateCertFromNSSHandles(
64     CERTCertificate* cert_handle,
65     const std::vector<CERTCertificate*>& intermediates) {
66   ScopedCFTypeRef<SecCertificateRef> os_server_cert(
67       CreateOSCertHandleFromNSSHandle(cert_handle));
68   if (!os_server_cert)
69     return NULL;
70   std::vector<SecCertificateRef> os_intermediates;
71   for (size_t i = 0; i < intermediates.size(); ++i) {
72     SecCertificateRef intermediate =
73         CreateOSCertHandleFromNSSHandle(intermediates[i]);
74     if (!intermediate)
75       break;
76     os_intermediates.push_back(intermediate);
77   }
78
79   X509Certificate* cert = NULL;
80   if (intermediates.size() == os_intermediates.size()) {
81     cert = X509Certificate::CreateFromHandle(os_server_cert,
82                                              os_intermediates);
83   }
84
85   for (size_t i = 0; i < os_intermediates.size(); ++i)
86     CFRelease(os_intermediates[i]);
87   return cert;
88 }
89
90 SHA1HashValue CalculateFingerprintNSS(CERTCertificate* cert) {
91   DCHECK(cert->derCert.data);
92   DCHECK_NE(0U, cert->derCert.len);
93   SHA1HashValue sha1;
94   memset(sha1.data, 0, sizeof(sha1.data));
95   CC_SHA1(cert->derCert.data, cert->derCert.len, sha1.data);
96   return sha1;
97 }
98
99 // NSSCertificate implementation.
100
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*";
105 }
106
107 NSSCertificate::~NSSCertificate() {
108   CERT_DestroyCertificate(nss_cert_handle_);
109 }
110
111 CERTCertificate* NSSCertificate::cert_handle() const {
112   return nss_cert_handle_;
113 }
114
115 // NSSCertChain implementation
116
117 NSSCertChain::NSSCertChain(X509Certificate* certificate) {
118   DCHECK(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]));
125 }
126
127 NSSCertChain::~NSSCertChain() {
128   for (size_t i = 0; i < certs_.size(); ++i)
129     CERT_DestroyCertificate(certs_[i]);
130 }
131
132 CERTCertificate* NSSCertChain::cert_handle() const {
133   return certs_.empty() ? NULL : certs_.front();
134 }
135
136 const std::vector<CERTCertificate*>& NSSCertChain::cert_chain() const {
137   return certs_;
138 }
139
140 }  // namespace x509_util_ios
141 }  // namespace net