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 <openssl/evp.h> | 7 #include <openssl/evp.h> |
8 #include <openssl/rsa.h> | 8 #include <openssl/rsa.h> |
9 #include <openssl/x509.h> | 9 #include <openssl/x509.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 "failed to verify credentials: cert not signed by trusted CA", | 55 "failed to verify credentials: cert not signed by trusted CA", |
56 AuthResult::ERROR_FINGERPRINT_NOT_FOUND); | 56 AuthResult::ERROR_FINGERPRINT_NOT_FOUND); |
57 } | 57 } |
58 } | 58 } |
59 | 59 |
60 // Parse the CA public key. | 60 // Parse the CA public key. |
61 const uint8_t* ca_ptr = | 61 const uint8_t* ca_ptr = |
62 reinterpret_cast<const uint8_t*>(ca_public_key_bytes.data()); | 62 reinterpret_cast<const uint8_t*>(ca_public_key_bytes.data()); |
63 const uint8_t* ca_public_key_end = ca_ptr + ca_public_key_bytes.size(); | 63 const uint8_t* ca_public_key_end = ca_ptr + ca_public_key_bytes.size(); |
64 crypto::ScopedRSA ca_public_key_rsa( | 64 crypto::ScopedRSA ca_public_key_rsa( |
65 d2i_RSAPublicKey(NULL, &ca_ptr, ca_public_key_bytes.size())); | 65 d2i_RSAPublicKey(nullptr, &ca_ptr, ca_public_key_bytes.size())); |
66 if (!ca_public_key_rsa || ca_ptr != ca_public_key_end) { | 66 if (!ca_public_key_rsa || ca_ptr != ca_public_key_end) { |
67 LOG(ERROR) << "Failed to import trusted public key."; | 67 LOG(ERROR) << "Failed to import trusted public key."; |
68 return AuthResult::CreateWithParseError( | 68 return AuthResult::CreateWithParseError( |
69 "failed to import trusted public key.", | 69 "failed to import trusted public key.", |
70 AuthResult::ERROR_CERT_PARSING_FAILED); | 70 AuthResult::ERROR_CERT_PARSING_FAILED); |
71 } | 71 } |
72 crypto::ScopedEVP_PKEY ca_public_key(EVP_PKEY_new()); | 72 crypto::ScopedEVP_PKEY ca_public_key(EVP_PKEY_new()); |
73 if (!ca_public_key || | 73 if (!ca_public_key || |
74 !EVP_PKEY_set1_RSA(ca_public_key.get(), ca_public_key_rsa.get())) { | 74 !EVP_PKEY_set1_RSA(ca_public_key.get(), ca_public_key_rsa.get())) { |
75 LOG(ERROR) << "Failed to initialize EVP_PKEY"; | 75 LOG(ERROR) << "Failed to initialize EVP_PKEY"; |
76 return AuthResult::CreateWithParseError( | 76 return AuthResult::CreateWithParseError( |
77 "failed to initialize EVP_PKEY.", | 77 "failed to initialize EVP_PKEY.", |
78 AuthResult::ERROR_CANNOT_EXTRACT_PUBLIC_KEY); | 78 AuthResult::ERROR_CANNOT_EXTRACT_PUBLIC_KEY); |
79 } | 79 } |
80 | 80 |
81 // Parse the client auth certificate. | 81 // Parse the client auth certificate. |
82 const uint8_t* client_cert_ptr = reinterpret_cast<const uint8_t*>( | 82 const uint8_t* client_cert_ptr = reinterpret_cast<const uint8_t*>( |
83 response.client_auth_certificate().data()); | 83 response.client_auth_certificate().data()); |
84 const uint8_t* client_cert_end = | 84 const uint8_t* client_cert_end = |
85 client_cert_ptr + | 85 client_cert_ptr + |
86 response.client_auth_certificate().size(); | 86 response.client_auth_certificate().size(); |
87 const ScopedX509 client_cert( | 87 const ScopedX509 client_cert(d2i_X509( |
88 d2i_X509(NULL, &client_cert_ptr, | 88 nullptr, &client_cert_ptr, response.client_auth_certificate().size())); |
89 response.client_auth_certificate().size())); | |
90 if (!client_cert || client_cert_ptr != client_cert_end) { | 89 if (!client_cert || client_cert_ptr != client_cert_end) { |
91 LOG(ERROR) << "Failed to parse certificate."; | 90 LOG(ERROR) << "Failed to parse certificate."; |
92 return AuthResult::CreateWithParseError( | 91 return AuthResult::CreateWithParseError( |
93 "failed to parse client_auth_certificate.", | 92 "failed to parse client_auth_certificate.", |
94 AuthResult::ERROR_CERT_PARSING_FAILED); | 93 AuthResult::ERROR_CERT_PARSING_FAILED); |
95 } | 94 } |
96 | 95 |
97 // Verify that the client auth certificate was signed by a trusted CA. | 96 // Verify that the client auth certificate was signed by a trusted CA. |
98 if (X509_verify(client_cert.get(), ca_public_key.get()) <= 0) { | 97 if (X509_verify(client_cert.get(), ca_public_key.get()) <= 0) { |
99 LOG(ERROR) << "Certificate is not issued by a trusted CA."; | 98 LOG(ERROR) << "Certificate is not issued by a trusted CA."; |
(...skipping 11 matching lines...) Expand all Loading... |
111 << client_public_key_type << " instead."; | 110 << client_public_key_type << " instead."; |
112 return AuthResult::CreateWithParseError( | 111 return AuthResult::CreateWithParseError( |
113 "couldn't extract public_key from client cert.", | 112 "couldn't extract public_key from client cert.", |
114 AuthResult::ERROR_CANNOT_EXTRACT_PUBLIC_KEY); | 113 AuthResult::ERROR_CANNOT_EXTRACT_PUBLIC_KEY); |
115 } | 114 } |
116 | 115 |
117 // Check that the SSL peer certificate was signed using the client's public | 116 // Check that the SSL peer certificate was signed using the client's public |
118 // key. | 117 // key. |
119 const crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); | 118 const crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); |
120 if (!ctx || | 119 if (!ctx || |
121 !EVP_DigestVerifyInit(ctx.get(), NULL, EVP_sha1(), NULL, | 120 !EVP_DigestVerifyInit(ctx.get(), nullptr, EVP_sha1(), nullptr, |
122 client_public_key.get()) || | 121 client_public_key.get()) || |
123 !EVP_DigestVerifyUpdate(ctx.get(), peer_cert.data(), peer_cert.size())) { | 122 !EVP_DigestVerifyUpdate(ctx.get(), peer_cert.data(), peer_cert.size())) { |
124 return AuthResult::CreateWithParseError( | 123 return AuthResult::CreateWithParseError( |
125 "error initializing payload verification operation.", | 124 "error initializing payload verification operation.", |
126 AuthResult::ERROR_UNEXPECTED_AUTH_LIBRARY_RESULT); | 125 AuthResult::ERROR_UNEXPECTED_AUTH_LIBRARY_RESULT); |
127 } | 126 } |
128 const std::string& signature = response.signature(); | 127 const std::string& signature = response.signature(); |
129 if (EVP_DigestVerifyFinal( | 128 if (EVP_DigestVerifyFinal( |
130 ctx.get(), | 129 ctx.get(), |
131 reinterpret_cast<uint8_t*>(const_cast<char*>(signature.data())), | 130 reinterpret_cast<uint8_t*>(const_cast<char*>(signature.data())), |
132 signature.size()) <= 0) { | 131 signature.size()) <= 0) { |
133 return AuthResult::CreateWithParseError( | 132 return AuthResult::CreateWithParseError( |
134 "payload verification failed.", | 133 "payload verification failed.", |
135 AuthResult::ERROR_SIGNED_BLOBS_MISMATCH); | 134 AuthResult::ERROR_SIGNED_BLOBS_MISMATCH); |
136 } | 135 } |
137 | 136 |
138 return AuthResult(); | 137 return AuthResult(); |
139 } | 138 } |
140 | 139 |
141 } // namespace cast_channel | 140 } // namespace cast_channel |
142 } // namespace core_api | 141 } // namespace core_api |
143 } // namespace extensions | 142 } // namespace extensions |
144 | 143 |
OLD | NEW |