Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_auth_util.h" | 5 #include "extensions/browser/api/cast_channel/cast_auth_util.h" |
| 6 | 6 |
| 7 #include <cert.h> | 7 #include <cert.h> |
| 8 #include <cryptohi.h> | 8 #include <cryptohi.h> |
| 9 #include <pk11pub.h> | 9 #include <pk11pub.h> |
| 10 #include <seccomon.h> | 10 #include <seccomon.h> |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 namespace extensions { | 23 namespace extensions { |
| 24 namespace core_api { | 24 namespace core_api { |
| 25 namespace cast_channel { | 25 namespace cast_channel { |
| 26 namespace { | 26 namespace { |
| 27 typedef scoped_ptr< | 27 typedef scoped_ptr< |
| 28 CERTCertificate, | 28 CERTCertificate, |
| 29 crypto::NSSDestroyer<CERTCertificate, CERT_DestroyCertificate> > | 29 crypto::NSSDestroyer<CERTCertificate, CERT_DestroyCertificate> > |
| 30 ScopedCERTCertificate; | 30 ScopedCERTCertificate; |
| 31 | 31 |
| 32 // Authenticates the given credentials: | 32 // Authenticates the given credentials: |
| 33 // 1. |signature| verification of |data| using |certificate|. | 33 // 1. |signature| verification of |peer_cert| using |certificate|. |
| 34 // 2. |certificate| is signed by a trusted CA. | 34 // 2. |certificate| is signed by a trusted CA. |
| 35 AuthResult VerifyCredentials(const AuthResponse& response, | 35 AuthResult VerifyCredentials(const AuthResponse& response, |
| 36 const std::string& data) { | 36 const std::string& peer_cert) { |
| 37 const std::string kErrorPrefix("Failed to verify credentials: "); | 37 const std::string kErrorPrefix("Failed to verify credentials: "); |
| 38 const std::string& certificate = response.client_auth_certificate(); | 38 const std::string& certificate = response.client_auth_certificate(); |
| 39 const std::string& signature = response.signature(); | 39 const std::string& signature = response.signature(); |
| 40 | 40 |
| 41 // If the list of intermediates is empty then use kPublicKeyICA1 as | 41 // If the list of intermediates is empty then use kPublicKeyICA1 as |
| 42 // the trusted CA (legacy case). | 42 // the trusted CA (legacy case). |
| 43 // Otherwise, use the first intermediate in the list as long as it | 43 // Otherwise, use the first intermediate in the list as long as it |
| 44 // is in the allowed list of intermediates. | 44 // is in the allowed list of intermediates. |
| 45 int num_intermediates = response.intermediate_certificate_size(); | 45 int num_intermediates = response.intermediate_certificate_size(); |
| 46 | 46 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 "Failed to parse certificate.", | 79 "Failed to parse certificate.", |
| 80 AuthResult::ERROR_NSS_CERT_PARSING_FAILED, | 80 AuthResult::ERROR_NSS_CERT_PARSING_FAILED, |
| 81 PORT_GetError()); | 81 PORT_GetError()); |
| 82 } | 82 } |
| 83 | 83 |
| 84 // Check that the certificate is signed by trusted CA. | 84 // Check that the certificate is signed by trusted CA. |
| 85 // NOTE: We const_cast trusted_ca_key_der since on some platforms | 85 // NOTE: We const_cast trusted_ca_key_der since on some platforms |
| 86 // SECKEY_ImportDERPublicKey API takes in SECItem* and not const | 86 // SECKEY_ImportDERPublicKey API takes in SECItem* and not const |
| 87 // SECItem*. | 87 // SECItem*. |
| 88 crypto::ScopedSECKEYPublicKey ca_public_key( | 88 crypto::ScopedSECKEYPublicKey ca_public_key( |
| 89 SECKEY_ImportDERPublicKey(&trusted_ca_key_der, CKK_RSA)); | 89 SECKEY_ImportDERPublicKey(&trusted_ca_key_der, CKK_RSA)); |
|
davidben
2014/10/30 18:37:22
Minor: While you're here, may as well check for ca
Kevin M
2014/10/31 21:39:37
Done.
| |
| 90 SECStatus verified = CERT_VerifySignedDataWithPublicKey( | 90 SECStatus verified = CERT_VerifySignedDataWithPublicKey( |
| 91 &cert->signatureWrap, ca_public_key.get(), NULL); | 91 &cert->signatureWrap, ca_public_key.get(), NULL); |
| 92 if (verified != SECSuccess) { | 92 if (verified != SECSuccess) { |
| 93 return AuthResult::CreateWithNSSError( | 93 return AuthResult::CreateWithNSSError( |
| 94 "Cert not signed by trusted CA", | 94 "Cert not signed by trusted CA", |
| 95 AuthResult::ERROR_NSS_CERT_NOT_SIGNED_BY_TRUSTED_CA, | 95 AuthResult::ERROR_NSS_CERT_NOT_SIGNED_BY_TRUSTED_CA, |
| 96 PORT_GetError()); | 96 PORT_GetError()); |
| 97 } | 97 } |
| 98 | 98 |
| 99 VLOG(1) << "Cert signed by trusted CA"; | 99 VLOG(1) << "Cert signed by trusted CA"; |
| 100 | 100 |
| 101 // Verify that the |signature| matches |data|. | 101 // Verify that the |signature| matches |peer_cert|. |
| 102 crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert.get())); | 102 crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert.get())); |
| 103 if (!public_key.get()) { | 103 if (!public_key.get()) { |
| 104 return AuthResult::CreateWithNSSError( | 104 return AuthResult::CreateWithNSSError( |
| 105 "Unable to extract public key from certificate", | 105 "Unable to extract public key from certificate", |
| 106 AuthResult::ERROR_NSS_CANNOT_EXTRACT_PUBLIC_KEY, | 106 AuthResult::ERROR_NSS_CANNOT_EXTRACT_PUBLIC_KEY, |
| 107 PORT_GetError()); | 107 PORT_GetError()); |
| 108 } | 108 } |
| 109 SECItem signature_item; | 109 SECItem signature_item; |
| 110 signature_item.type = siBuffer; | 110 signature_item.type = siBuffer; |
| 111 signature_item.data = reinterpret_cast<unsigned char*>( | 111 signature_item.data = reinterpret_cast<unsigned char*>( |
| 112 const_cast<char*>(signature.data())); | 112 const_cast<char*>(signature.data())); |
| 113 signature_item.len = signature.length(); | 113 signature_item.len = signature.length(); |
| 114 verified = VFY_VerifyDataDirect( | 114 verified = VFY_VerifyDataDirect( |
| 115 reinterpret_cast<unsigned char*>(const_cast<char*>(data.data())), | 115 reinterpret_cast<unsigned char*>(const_cast<char*>(peer_cert.data())), |
| 116 data.size(), | 116 data.size(), |
| 117 public_key.get(), | 117 public_key.get(), |
| 118 &signature_item, | 118 &signature_item, |
| 119 SEC_OID_PKCS1_RSA_ENCRYPTION, | 119 SEC_OID_PKCS1_RSA_ENCRYPTION, |
| 120 SEC_OID_SHA1, NULL, NULL); | 120 SEC_OID_SHA1, NULL, NULL); |
| 121 | 121 |
| 122 if (verified != SECSuccess) { | 122 if (verified != SECSuccess) { |
| 123 return AuthResult::CreateWithNSSError( | 123 return AuthResult::CreateWithNSSError( |
| 124 "Signed blobs did not match", | 124 "Signed blobs did not match", |
| 125 AuthResult::ERROR_NSS_SIGNED_BLOBS_MISMATCH, | 125 AuthResult::ERROR_NSS_SIGNED_BLOBS_MISMATCH, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 << ", NSS error code: " << result.nss_error_code; | 157 << ", NSS error code: " << result.nss_error_code; |
| 158 return result; | 158 return result; |
| 159 } | 159 } |
| 160 | 160 |
| 161 return AuthResult(); | 161 return AuthResult(); |
| 162 } | 162 } |
| 163 | 163 |
| 164 } // namespace cast_channel | 164 } // namespace cast_channel |
| 165 } // namespace core_api | 165 } // namespace core_api |
| 166 } // namespace extensions | 166 } // namespace extensions |
| OLD | NEW |