Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(661)

Side by Side Diff: net/cert/x509_util_win.cc

Issue 2913253003: Convert Windows to use X509CertificateBytes. (Closed)
Patch Set: rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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_win.h"
6
7 #include "crypto/scoped_capi_types.h"
8 #include "crypto/sha2.h"
9 #include "net/cert/x509_certificate.h"
10 #include "net/net_features.h"
11 #include "third_party/boringssl/src/include/openssl/pool.h"
12
13 namespace net {
14
15 namespace x509_util {
16
17 namespace {
18
19 using ScopedHCERTSTORE = crypto::ScopedCAPIHandle<
20 HCERTSTORE,
21 crypto::CAPIDestroyerWithFlags<HCERTSTORE, CertCloseStore, 0>>;
22
23 } // namespace
24
25 scoped_refptr<X509Certificate> CreateX509CertificateFromCertContexts(
26 PCCERT_CONTEXT os_cert,
27 const std::vector<PCCERT_CONTEXT>& os_chain) {
28 #if BUILDFLAG(USE_BYTE_CERTS)
29 if (!os_cert || !os_cert->pbCertEncoded || !os_cert->cbCertEncoded)
30 return nullptr;
31 bssl::UniquePtr<CRYPTO_BUFFER> cert_handle(
32 X509Certificate::CreateOSCertHandleFromBytes(
33 reinterpret_cast<const char*>(os_cert->pbCertEncoded),
34 os_cert->cbCertEncoded));
35 if (!cert_handle)
36 return nullptr;
37 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
38 X509Certificate::OSCertHandles intermediates_raw;
39 for (PCCERT_CONTEXT os_intermediate : os_chain) {
40 if (!os_intermediate || !os_intermediate->pbCertEncoded ||
41 !os_intermediate->cbCertEncoded)
42 return nullptr;
43 bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle(
44 X509Certificate::CreateOSCertHandleFromBytes(
45 reinterpret_cast<const char*>(os_intermediate->pbCertEncoded),
46 os_intermediate->cbCertEncoded));
47 if (!intermediate_cert_handle)
48 return nullptr;
49 intermediates_raw.push_back(intermediate_cert_handle.get());
50 intermediates.push_back(std::move(intermediate_cert_handle));
51 }
52 scoped_refptr<X509Certificate> result(
53 X509Certificate::CreateFromHandle(cert_handle.get(), intermediates_raw));
54 return result;
55 #else
56 return X509Certificate::CreateFromHandle(os_cert, os_chain);
57 #endif
58 }
59
60 ScopedPCCERT_CONTEXT CreateCertContextWithChain(const X509Certificate* cert) {
61 // Create an in-memory certificate store to hold the certificate and its
62 // intermediate certificates. The store will be referenced in the returned
63 // PCCERT_CONTEXT, and will not be freed until the PCCERT_CONTEXT is freed.
64 ScopedHCERTSTORE store(
65 CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL,
66 CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL));
67 if (!store.get())
68 return nullptr;
69
70 PCCERT_CONTEXT primary_cert = nullptr;
71
72 #if BUILDFLAG(USE_BYTE_CERTS)
73 BOOL ok = CertAddEncodedCertificateToStore(
74 store.get(), X509_ASN_ENCODING,
75 CRYPTO_BUFFER_data(cert->os_cert_handle()),
76 base::checked_cast<DWORD>(CRYPTO_BUFFER_len(cert->os_cert_handle())),
77 CERT_STORE_ADD_ALWAYS, &primary_cert);
78 if (!ok || !primary_cert)
79 return nullptr;
80 ScopedPCCERT_CONTEXT scoped_primary_cert(primary_cert);
81
82 for (X509Certificate::OSCertHandle intermediate :
83 cert->GetIntermediateCertificates()) {
84 ok = CertAddEncodedCertificateToStore(
85 store.get(), X509_ASN_ENCODING, CRYPTO_BUFFER_data(intermediate),
86 base::checked_cast<DWORD>(CRYPTO_BUFFER_len(intermediate)),
87 CERT_STORE_ADD_ALWAYS, NULL);
88 if (!ok)
89 return nullptr;
90 }
91 #else
92 PCCERT_CONTEXT os_cert_handle = cert->os_cert_handle();
93 const std::vector<PCCERT_CONTEXT>& intermediate_ca_certs =
94 cert->GetIntermediateCertificates();
95
96 // NOTE: This preserves all of the properties of |os_cert_handle| except
97 // for CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID - the two
98 // properties that hold access to already-opened private keys. If a handle
99 // has already been unlocked (eg: PIN prompt), then the first time that the
100 // identity is used for client auth, it may prompt the user again.
101 BOOL ok = CertAddCertificateContextToStore(
102 store.get(), os_cert_handle, CERT_STORE_ADD_ALWAYS, &primary_cert);
103 if (!ok || !primary_cert)
104 return nullptr;
105 ScopedPCCERT_CONTEXT scoped_primary_cert(primary_cert);
106
107 for (PCCERT_CONTEXT intermediate : intermediate_ca_certs) {
108 CertAddCertificateContextToStore(store.get(), intermediate,
109 CERT_STORE_ADD_ALWAYS, NULL);
110 }
111 #endif
112
113 // Note: |primary_cert| retains a reference to |store|, so the store will
114 // actually be freed when |primary_cert| is freed.
115 return scoped_primary_cert;
116 }
117
118 SHA256HashValue CalculateFingerprint256(PCCERT_CONTEXT cert) {
119 DCHECK(NULL != cert->pbCertEncoded);
120 DCHECK_NE(0u, cert->cbCertEncoded);
121
122 SHA256HashValue sha256;
123
124 // Use crypto::SHA256HashString for two reasons:
125 // * < Windows Vista does not have universal SHA-256 support.
126 // * More efficient on Windows > Vista (less overhead since non-default CSP
127 // is not needed).
128 base::StringPiece der_cert(reinterpret_cast<const char*>(cert->pbCertEncoded),
129 cert->cbCertEncoded);
130 crypto::SHA256HashString(der_cert, sha256.data, sizeof(sha256.data));
131 return sha256;
132 }
133
134 bool IsSelfSigned(PCCERT_CONTEXT cert_handle) {
135 bool valid_signature = !!CryptVerifyCertificateSignatureEx(
136 NULL, X509_ASN_ENCODING, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT,
137 reinterpret_cast<void*>(const_cast<PCERT_CONTEXT>(cert_handle)),
138 CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT,
139 reinterpret_cast<void*>(const_cast<PCERT_CONTEXT>(cert_handle)), 0, NULL);
140 if (!valid_signature)
141 return false;
142 return !!CertCompareCertificateName(X509_ASN_ENCODING,
143 &cert_handle->pCertInfo->Subject,
144 &cert_handle->pCertInfo->Issuer);
145 }
146
147 } // namespace x509_util
148
149 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/x509_util_win.h ('k') | net/data/parse_certificate_unittest/signature_algorithm_null.pem » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698