| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert/ct_objects_extractor.h" | 5 #include "net/cert/ct_objects_extractor.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <openssl/bytestring.h> | 9 #include <openssl/bytestring.h> |
| 10 #include <openssl/obj.h> | 10 #include <openssl/obj.h> |
| 11 #include <openssl/x509.h> | 11 #include <openssl/x509.h> |
| 12 | 12 |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/sha1.h" | 14 #include "base/sha1.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "crypto/scoped_openssl_types.h" | |
| 17 #include "crypto/sha2.h" | 16 #include "crypto/sha2.h" |
| 18 #include "net/cert/asn1_util.h" | 17 #include "net/cert/asn1_util.h" |
| 19 #include "net/cert/signed_certificate_timestamp.h" | 18 #include "net/cert/signed_certificate_timestamp.h" |
| 20 #include "net/ssl/scoped_openssl_types.h" | |
| 21 | 19 |
| 22 namespace net { | 20 namespace net { |
| 23 | 21 |
| 24 namespace ct { | 22 namespace ct { |
| 25 | 23 |
| 26 namespace { | 24 namespace { |
| 27 | 25 |
| 28 void FreeX509_EXTENSIONS(X509_EXTENSIONS* ptr) { | |
| 29 sk_X509_EXTENSION_pop_free(ptr, X509_EXTENSION_free); | |
| 30 } | |
| 31 | |
| 32 using ScopedX509_EXTENSIONS = | |
| 33 crypto::ScopedOpenSSL<X509_EXTENSIONS, FreeX509_EXTENSIONS>; | |
| 34 | |
| 35 // The wire form of the OID 1.3.6.1.4.1.11129.2.4.2. See Section 3.3 of | 26 // The wire form of the OID 1.3.6.1.4.1.11129.2.4.2. See Section 3.3 of |
| 36 // RFC6962. | 27 // RFC6962. |
| 37 const uint8_t kEmbeddedSCTOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01, | 28 const uint8_t kEmbeddedSCTOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01, |
| 38 0xD6, 0x79, 0x02, 0x04, 0x02}; | 29 0xD6, 0x79, 0x02, 0x04, 0x02}; |
| 39 | 30 |
| 40 // The wire form of the OID 1.3.6.1.4.1.11129.2.4.5 - OCSP SingleExtension for | 31 // The wire form of the OID 1.3.6.1.4.1.11129.2.4.5 - OCSP SingleExtension for |
| 41 // X.509v3 Certificate Transparency Signed Certificate Timestamp List, see | 32 // X.509v3 Certificate Transparency Signed Certificate Timestamp List, see |
| 42 // Section 3.3 of RFC6962. | 33 // Section 3.3 of RFC6962. |
| 43 const uint8_t kOCSPExtensionOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01, | 34 const uint8_t kOCSPExtensionOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01, |
| 44 0xD6, 0x79, 0x02, 0x04, 0x05}; | 35 0xD6, 0x79, 0x02, 0x04, 0x05}; |
| 45 | 36 |
| 46 bool StringEqualToCBS(const std::string& value1, const CBS* value2) { | 37 bool StringEqualToCBS(const std::string& value1, const CBS* value2) { |
| 47 if (CBS_len(value2) != value1.size()) | 38 if (CBS_len(value2) != value1.size()) |
| 48 return false; | 39 return false; |
| 49 return memcmp(value1.data(), CBS_data(value2), CBS_len(value2)) == 0; | 40 return memcmp(value1.data(), CBS_data(value2), CBS_len(value2)) == 0; |
| 50 } | 41 } |
| 51 | 42 |
| 52 ScopedX509 OSCertHandleToOpenSSL(X509Certificate::OSCertHandle os_handle) { | 43 bssl::UniquePtr<X509> OSCertHandleToOpenSSL( |
| 44 X509Certificate::OSCertHandle os_handle) { |
| 53 #if defined(USE_OPENSSL_CERTS) | 45 #if defined(USE_OPENSSL_CERTS) |
| 54 return ScopedX509(X509Certificate::DupOSCertHandle(os_handle)); | 46 return bssl::UniquePtr<X509>(X509Certificate::DupOSCertHandle(os_handle)); |
| 55 #else | 47 #else |
| 56 std::string der_encoded; | 48 std::string der_encoded; |
| 57 if (!X509Certificate::GetDEREncoded(os_handle, &der_encoded)) | 49 if (!X509Certificate::GetDEREncoded(os_handle, &der_encoded)) |
| 58 return ScopedX509(); | 50 return bssl::UniquePtr<X509>(); |
| 59 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(der_encoded.data()); | 51 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(der_encoded.data()); |
| 60 return ScopedX509(d2i_X509(NULL, &bytes, der_encoded.size())); | 52 return bssl::UniquePtr<X509>(d2i_X509(NULL, &bytes, der_encoded.size())); |
| 61 #endif | 53 #endif |
| 62 } | 54 } |
| 63 | 55 |
| 64 // Finds the SignedCertificateTimestampList in an extension with OID |oid| in | 56 // Finds the SignedCertificateTimestampList in an extension with OID |oid| in |
| 65 // |x509_exts|. If found, returns true and sets |*out_sct_list| to the encoded | 57 // |x509_exts|. If found, returns true and sets |*out_sct_list| to the encoded |
| 66 // SCT list. |out_sct_list| may be NULL. | 58 // SCT list. |out_sct_list| may be NULL. |
| 67 bool GetSCTListFromX509_EXTENSIONS(const X509_EXTENSIONS* x509_exts, | 59 bool GetSCTListFromX509_EXTENSIONS(const X509_EXTENSIONS* x509_exts, |
| 68 const uint8_t* oid, | 60 const uint8_t* oid, |
| 69 size_t oid_len, | 61 size_t oid_len, |
| 70 std::string* out_sct_list) { | 62 std::string* out_sct_list) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 156 } |
| 165 } | 157 } |
| 166 | 158 |
| 167 return false; | 159 return false; |
| 168 } | 160 } |
| 169 | 161 |
| 170 } // namespace | 162 } // namespace |
| 171 | 163 |
| 172 bool ExtractEmbeddedSCTList(X509Certificate::OSCertHandle cert, | 164 bool ExtractEmbeddedSCTList(X509Certificate::OSCertHandle cert, |
| 173 std::string* sct_list) { | 165 std::string* sct_list) { |
| 174 ScopedX509 x509(OSCertHandleToOpenSSL(cert)); | 166 bssl::UniquePtr<X509> x509(OSCertHandleToOpenSSL(cert)); |
| 175 if (!x509) | 167 if (!x509) |
| 176 return false; | 168 return false; |
| 177 X509_EXTENSIONS* x509_exts = x509->cert_info->extensions; | 169 X509_EXTENSIONS* x509_exts = x509->cert_info->extensions; |
| 178 if (!x509_exts) | 170 if (!x509_exts) |
| 179 return false; | 171 return false; |
| 180 return GetSCTListFromX509_EXTENSIONS(x509->cert_info->extensions, | 172 return GetSCTListFromX509_EXTENSIONS(x509->cert_info->extensions, |
| 181 kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid), | 173 kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid), |
| 182 sct_list); | 174 sct_list); |
| 183 } | 175 } |
| 184 | 176 |
| 185 bool GetPrecertLogEntry(X509Certificate::OSCertHandle leaf, | 177 bool GetPrecertLogEntry(X509Certificate::OSCertHandle leaf, |
| 186 X509Certificate::OSCertHandle issuer, | 178 X509Certificate::OSCertHandle issuer, |
| 187 LogEntry* result) { | 179 LogEntry* result) { |
| 188 result->Reset(); | 180 result->Reset(); |
| 189 | 181 |
| 190 ScopedX509 leaf_x509(OSCertHandleToOpenSSL(leaf)); | 182 bssl::UniquePtr<X509> leaf_x509(OSCertHandleToOpenSSL(leaf)); |
| 191 if (!leaf_x509) | 183 if (!leaf_x509) |
| 192 return false; | 184 return false; |
| 193 | 185 |
| 194 // XXX(rsleevi): This check may be overkill, since we should be able to | 186 // XXX(rsleevi): This check may be overkill, since we should be able to |
| 195 // generate precerts for certs without the extension. For now, just a sanity | 187 // generate precerts for certs without the extension. For now, just a sanity |
| 196 // check to match the reference implementation. | 188 // check to match the reference implementation. |
| 197 if (!leaf_x509->cert_info->extensions || | 189 if (!leaf_x509->cert_info->extensions || |
| 198 !GetSCTListFromX509_EXTENSIONS(leaf_x509->cert_info->extensions, | 190 !GetSCTListFromX509_EXTENSIONS(leaf_x509->cert_info->extensions, |
| 199 kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid), | 191 kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid), |
| 200 NULL)) { | 192 NULL)) { |
| 201 return false; | 193 return false; |
| 202 } | 194 } |
| 203 | 195 |
| 204 // The Precertificate log entry is the final certificate's TBSCertificate | 196 // The Precertificate log entry is the final certificate's TBSCertificate |
| 205 // without the SCT extension (RFC6962, section 3.2). | 197 // without the SCT extension (RFC6962, section 3.2). |
| 206 ScopedX509 leaf_copy(X509_dup(leaf_x509.get())); | 198 bssl::UniquePtr<X509> leaf_copy(X509_dup(leaf_x509.get())); |
| 207 if (!leaf_copy || !leaf_copy->cert_info->extensions) { | 199 if (!leaf_copy || !leaf_copy->cert_info->extensions) { |
| 208 NOTREACHED(); | 200 NOTREACHED(); |
| 209 return false; | 201 return false; |
| 210 } | 202 } |
| 211 X509_EXTENSIONS* leaf_copy_exts = leaf_copy->cert_info->extensions; | 203 X509_EXTENSIONS* leaf_copy_exts = leaf_copy->cert_info->extensions; |
| 212 for (size_t i = 0; i < sk_X509_EXTENSION_num(leaf_copy_exts); i++) { | 204 for (size_t i = 0; i < sk_X509_EXTENSION_num(leaf_copy_exts); i++) { |
| 213 X509_EXTENSION* ext = sk_X509_EXTENSION_value(leaf_copy_exts, i); | 205 X509_EXTENSION* ext = sk_X509_EXTENSION_value(leaf_copy_exts, i); |
| 214 if (static_cast<size_t>(ext->object->length) == sizeof(kEmbeddedSCTOid) && | 206 if (static_cast<size_t>(ext->object->length) == sizeof(kEmbeddedSCTOid) && |
| 215 memcmp(ext->object->data, kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid)) == | 207 memcmp(ext->object->data, kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid)) == |
| 216 0) { | 208 0) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 if (CBS_len(&single_response) > 0 && | 331 if (CBS_len(&single_response) > 0 && |
| 340 CBS_data(&single_response)[0] == kNextUpdateTag && | 332 CBS_data(&single_response)[0] == kNextUpdateTag && |
| 341 !CBS_get_asn1(&single_response, NULL /* nextUpdate */, kNextUpdateTag)) { | 333 !CBS_get_asn1(&single_response, NULL /* nextUpdate */, kNextUpdateTag)) { |
| 342 return false; | 334 return false; |
| 343 } | 335 } |
| 344 | 336 |
| 345 CBS extensions; | 337 CBS extensions; |
| 346 if (!CBS_get_asn1(&single_response, &extensions, kSingleExtensionsTag)) | 338 if (!CBS_get_asn1(&single_response, &extensions, kSingleExtensionsTag)) |
| 347 return false; | 339 return false; |
| 348 const uint8_t* ptr = CBS_data(&extensions); | 340 const uint8_t* ptr = CBS_data(&extensions); |
| 349 ScopedX509_EXTENSIONS x509_exts( | 341 bssl::UniquePtr<X509_EXTENSIONS> x509_exts( |
| 350 d2i_X509_EXTENSIONS(NULL, &ptr, CBS_len(&extensions))); | 342 d2i_X509_EXTENSIONS(NULL, &ptr, CBS_len(&extensions))); |
| 351 if (!x509_exts || ptr != CBS_data(&extensions) + CBS_len(&extensions)) | 343 if (!x509_exts || ptr != CBS_data(&extensions) + CBS_len(&extensions)) |
| 352 return false; | 344 return false; |
| 353 | 345 |
| 354 return GetSCTListFromX509_EXTENSIONS(x509_exts.get(), kOCSPExtensionOid, | 346 return GetSCTListFromX509_EXTENSIONS(x509_exts.get(), kOCSPExtensionOid, |
| 355 sizeof(kOCSPExtensionOid), sct_list); | 347 sizeof(kOCSPExtensionOid), sct_list); |
| 356 } | 348 } |
| 357 | 349 |
| 358 } // namespace ct | 350 } // namespace ct |
| 359 | 351 |
| 360 } // namespace net | 352 } // namespace net |
| OLD | NEW |