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

Side by Side Diff: extensions/browser/api/cast_channel/cast_auth_util_nss.cc

Issue 687733004: Implement crypto signature verification routines using OpenSSL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix const truncation warning (raised by Win builds.) Created 6 years, 1 month 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
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>
11 #include <string> 11 #include <string>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/strings/string_piece.h" 14 #include "base/strings/string_piece.h"
15 #include "crypto/nss_util.h" 15 #include "crypto/nss_util.h"
16 #include "crypto/scoped_nss_types.h" 16 #include "crypto/scoped_nss_types.h"
17 #include "extensions/browser/api/cast_channel/cast_auth_ica.h" 17 #include "extensions/browser/api/cast_channel/cast_auth_ica.h"
18 #include "extensions/browser/api/cast_channel/cast_message_util.h" 18 #include "extensions/browser/api/cast_channel/cast_message_util.h"
19 #include "extensions/common/api/cast_channel/cast_channel.pb.h" 19 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
20 #include "net/base/hash_value.h" 20 #include "net/base/hash_value.h"
21 #include "net/cert/x509_certificate.h" 21 #include "net/cert/x509_certificate.h"
22 22
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
27 typedef scoped_ptr< 28 typedef scoped_ptr<
28 CERTCertificate, 29 CERTCertificate,
29 crypto::NSSDestroyer<CERTCertificate, CERT_DestroyCertificate> > 30 crypto::NSSDestroyer<CERTCertificate, CERT_DestroyCertificate> >
30 ScopedCERTCertificate; 31 ScopedCERTCertificate;
31 32
33 } // namespace
34
32 // Authenticates the given credentials: 35 // Authenticates the given credentials:
33 // 1. |signature| verification of |data| using |certificate|. 36 // 1. |signature| verification of |peer_cert| using |certificate|.
34 // 2. |certificate| is signed by a trusted CA. 37 // 2. |certificate| is signed by a trusted CA.
35 AuthResult VerifyCredentials(const AuthResponse& response, 38 AuthResult VerifyCredentials(const AuthResponse& response,
36 const std::string& data) { 39 const std::string& peer_cert) {
37 const std::string kErrorPrefix("Failed to verify credentials: "); 40 const std::string kErrorPrefix("Failed to verify credentials: ");
38 const std::string& certificate = response.client_auth_certificate(); 41 const std::string& certificate = response.client_auth_certificate();
39 const std::string& signature = response.signature(); 42 const std::string& signature = response.signature();
40 43
41 // If the list of intermediates is empty then use kPublicKeyICA1 as 44 // If the list of intermediates is empty then use kPublicKeyICA1 as
42 // the trusted CA (legacy case). 45 // the trusted CA (legacy case).
43 // Otherwise, use the first intermediate in the list as long as it 46 // Otherwise, use the first intermediate in the list as long as it
44 // is in the allowed list of intermediates. 47 // is in the allowed list of intermediates.
45 int num_intermediates = response.intermediate_certificate_size(); 48 int num_intermediates = response.intermediate_certificate_size();
46 49
(...skipping 24 matching lines...) Expand all
71 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>( 74 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
72 certificate.data())); 75 certificate.data()));
73 der_cert.len = certificate.length(); 76 der_cert.len = certificate.length();
74 77
75 // Parse into a certificate structure. 78 // Parse into a certificate structure.
76 ScopedCERTCertificate cert(CERT_NewTempCertificate( 79 ScopedCERTCertificate cert(CERT_NewTempCertificate(
77 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE)); 80 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE));
78 if (!cert.get()) { 81 if (!cert.get()) {
79 return AuthResult::CreateWithNSSError( 82 return AuthResult::CreateWithNSSError(
80 "Failed to parse certificate.", 83 "Failed to parse certificate.",
81 AuthResult::ERROR_NSS_CERT_PARSING_FAILED, PORT_GetError()); 84 AuthResult::ERROR_CERT_PARSING_FAILED, PORT_GetError());
82 } 85 }
83 86
84 // Check that the certificate is signed by trusted CA. 87 // Check that the certificate is signed by trusted CA.
85 // NOTE: We const_cast trusted_ca_key_der since on some platforms 88 // NOTE: We const_cast trusted_ca_key_der since on some platforms
86 // SECKEY_ImportDERPublicKey API takes in SECItem* and not const 89 // SECKEY_ImportDERPublicKey API takes in SECItem* and not const
87 // SECItem*. 90 // SECItem*.
88 crypto::ScopedSECKEYPublicKey ca_public_key( 91 crypto::ScopedSECKEYPublicKey ca_public_key(
89 SECKEY_ImportDERPublicKey(&trusted_ca_key_der, CKK_RSA)); 92 SECKEY_ImportDERPublicKey(&trusted_ca_key_der, CKK_RSA));
93 if (!ca_public_key) {
94 return AuthResult::CreateWithNSSError(
95 "Failed to import public key from CA certificate.",
96 AuthResult::ERROR_CERT_PARSING_FAILED, PORT_GetError());
97 }
90 SECStatus verified = CERT_VerifySignedDataWithPublicKey( 98 SECStatus verified = CERT_VerifySignedDataWithPublicKey(
91 &cert->signatureWrap, ca_public_key.get(), NULL); 99 &cert->signatureWrap, ca_public_key.get(), NULL);
92 if (verified != SECSuccess) { 100 if (verified != SECSuccess) {
93 return AuthResult::CreateWithNSSError( 101 return AuthResult::CreateWithNSSError(
94 "Cert not signed by trusted CA", 102 "Cert not signed by trusted CA",
95 AuthResult::ERROR_NSS_CERT_NOT_SIGNED_BY_TRUSTED_CA, PORT_GetError()); 103 AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA, PORT_GetError());
96 } 104 }
97 105
98 VLOG(1) << "Cert signed by trusted CA"; 106 VLOG(1) << "Cert signed by trusted CA";
99 107
100 // Verify that the |signature| matches |data|. 108 // Verify that the |signature| matches |peer_cert|.
101 crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert.get())); 109 crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert.get()));
102 if (!public_key.get()) { 110 if (!public_key.get()) {
103 return AuthResult::CreateWithNSSError( 111 return AuthResult::CreateWithNSSError(
104 "Unable to extract public key from certificate", 112 "Unable to extract public key from certificate",
105 AuthResult::ERROR_NSS_CANNOT_EXTRACT_PUBLIC_KEY, PORT_GetError()); 113 AuthResult::ERROR_CANNOT_EXTRACT_PUBLIC_KEY, PORT_GetError());
106 } 114 }
107 SECItem signature_item; 115 SECItem signature_item;
108 signature_item.type = siBuffer; 116 signature_item.type = siBuffer;
109 signature_item.data = reinterpret_cast<unsigned char*>( 117 signature_item.data = reinterpret_cast<unsigned char*>(
110 const_cast<char*>(signature.data())); 118 const_cast<char*>(signature.data()));
111 signature_item.len = signature.length(); 119 signature_item.len = signature.length();
112 verified = VFY_VerifyDataDirect( 120 verified = VFY_VerifyDataDirect(
113 reinterpret_cast<unsigned char*>(const_cast<char*>(data.data())), 121 reinterpret_cast<unsigned char*>(const_cast<char*>(peer_cert.data())),
114 data.size(), 122 peer_cert.size(),
115 public_key.get(), 123 public_key.get(),
116 &signature_item, 124 &signature_item,
117 SEC_OID_PKCS1_RSA_ENCRYPTION, 125 SEC_OID_PKCS1_RSA_ENCRYPTION,
118 SEC_OID_SHA1, NULL, NULL); 126 SEC_OID_SHA1, NULL, NULL);
119 127
120 if (verified != SECSuccess) { 128 if (verified != SECSuccess) {
121 return AuthResult::CreateWithNSSError( 129 return AuthResult::CreateWithNSSError(
122 "Signed blobs did not match", 130 "Signed blobs did not match",
123 AuthResult::ERROR_NSS_SIGNED_BLOBS_MISMATCH, 131 AuthResult::ERROR_SIGNED_BLOBS_MISMATCH,
124 PORT_GetError()); 132 PORT_GetError());
125 } 133 }
126 134
127 VLOG(1) << "Signature verification succeeded"; 135 VLOG(1) << "Signature verification succeeded";
128 136
129 return AuthResult(); 137 return AuthResult();
130 } 138 }
131 139
132 } // namespace
133
134 AuthResult AuthenticateChallengeReply(const CastMessage& challenge_reply,
135 const std::string& peer_cert) {
136 if (peer_cert.empty()) {
137 AuthResult result = AuthResult::CreateWithParseError(
138 "Peer cert was empty.", AuthResult::ERROR_PEER_CERT_EMPTY);
139 VLOG(1) << result.error_message;
140 return result;
141 }
142
143 VLOG(1) << "Challenge reply: " << CastMessageToString(challenge_reply);
144 DeviceAuthMessage auth_message;
145 AuthResult result = ParseAuthMessage(challenge_reply, &auth_message);
146 if (!result.success()) {
147 VLOG(1) << result.error_message;
148 return result;
149 }
150
151 const AuthResponse& response = auth_message.response();
152 result = VerifyCredentials(response, peer_cert);
153 if (!result.success()) {
154 VLOG(1) << result.error_message
155 << ", NSS error code: " << result.nss_error_code;
156 return result;
157 }
158
159 return AuthResult();
160 }
161
162 } // namespace cast_channel 140 } // namespace cast_channel
163 } // namespace core_api 141 } // namespace core_api
164 } // namespace extensions 142 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/api/cast_channel/cast_auth_util.cc ('k') | extensions/browser/api/cast_channel/cast_auth_util_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698