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 |