1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (C) 1995-1998 Eric Young ([email protected])
2*8fb009dcSAndroid Build Coastguard Worker * All rights reserved.
3*8fb009dcSAndroid Build Coastguard Worker *
4*8fb009dcSAndroid Build Coastguard Worker * This package is an SSL implementation written
5*8fb009dcSAndroid Build Coastguard Worker * by Eric Young ([email protected]).
6*8fb009dcSAndroid Build Coastguard Worker * The implementation was written so as to conform with Netscapes SSL.
7*8fb009dcSAndroid Build Coastguard Worker *
8*8fb009dcSAndroid Build Coastguard Worker * This library is free for commercial and non-commercial use as long as
9*8fb009dcSAndroid Build Coastguard Worker * the following conditions are aheared to. The following conditions
10*8fb009dcSAndroid Build Coastguard Worker * apply to all code found in this distribution, be it the RC4, RSA,
11*8fb009dcSAndroid Build Coastguard Worker * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12*8fb009dcSAndroid Build Coastguard Worker * included with this distribution is covered by the same copyright terms
13*8fb009dcSAndroid Build Coastguard Worker * except that the holder is Tim Hudson ([email protected]).
14*8fb009dcSAndroid Build Coastguard Worker *
15*8fb009dcSAndroid Build Coastguard Worker * Copyright remains Eric Young's, and as such any Copyright notices in
16*8fb009dcSAndroid Build Coastguard Worker * the code are not to be removed.
17*8fb009dcSAndroid Build Coastguard Worker * If this package is used in a product, Eric Young should be given attribution
18*8fb009dcSAndroid Build Coastguard Worker * as the author of the parts of the library used.
19*8fb009dcSAndroid Build Coastguard Worker * This can be in the form of a textual message at program startup or
20*8fb009dcSAndroid Build Coastguard Worker * in documentation (online or textual) provided with the package.
21*8fb009dcSAndroid Build Coastguard Worker *
22*8fb009dcSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
23*8fb009dcSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
24*8fb009dcSAndroid Build Coastguard Worker * are met:
25*8fb009dcSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the copyright
26*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
27*8fb009dcSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
28*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
29*8fb009dcSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
30*8fb009dcSAndroid Build Coastguard Worker * 3. All advertising materials mentioning features or use of this software
31*8fb009dcSAndroid Build Coastguard Worker * must display the following acknowledgement:
32*8fb009dcSAndroid Build Coastguard Worker * "This product includes cryptographic software written by
33*8fb009dcSAndroid Build Coastguard Worker * Eric Young ([email protected])"
34*8fb009dcSAndroid Build Coastguard Worker * The word 'cryptographic' can be left out if the rouines from the library
35*8fb009dcSAndroid Build Coastguard Worker * being used are not cryptographic related :-).
36*8fb009dcSAndroid Build Coastguard Worker * 4. If you include any Windows specific code (or a derivative thereof) from
37*8fb009dcSAndroid Build Coastguard Worker * the apps directory (application code) you must include an acknowledgement:
38*8fb009dcSAndroid Build Coastguard Worker * "This product includes software written by Tim Hudson ([email protected])"
39*8fb009dcSAndroid Build Coastguard Worker *
40*8fb009dcSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41*8fb009dcSAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*8fb009dcSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43*8fb009dcSAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44*8fb009dcSAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45*8fb009dcSAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46*8fb009dcSAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*8fb009dcSAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48*8fb009dcSAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49*8fb009dcSAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50*8fb009dcSAndroid Build Coastguard Worker * SUCH DAMAGE.
51*8fb009dcSAndroid Build Coastguard Worker *
52*8fb009dcSAndroid Build Coastguard Worker * The licence and distribution terms for any publically available version or
53*8fb009dcSAndroid Build Coastguard Worker * derivative of this code cannot be changed. i.e. this code cannot simply be
54*8fb009dcSAndroid Build Coastguard Worker * copied and put under another distribution licence
55*8fb009dcSAndroid Build Coastguard Worker * [including the GNU Public Licence.] */
56*8fb009dcSAndroid Build Coastguard Worker
57*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ssl.h>
58*8fb009dcSAndroid Build Coastguard Worker
59*8fb009dcSAndroid Build Coastguard Worker #include <assert.h>
60*8fb009dcSAndroid Build Coastguard Worker #include <limits.h>
61*8fb009dcSAndroid Build Coastguard Worker
62*8fb009dcSAndroid Build Coastguard Worker #include <algorithm>
63*8fb009dcSAndroid Build Coastguard Worker
64*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ec.h>
65*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ec_key.h>
66*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
67*8fb009dcSAndroid Build Coastguard Worker #include <openssl/evp.h>
68*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
69*8fb009dcSAndroid Build Coastguard Worker #include <openssl/span.h>
70*8fb009dcSAndroid Build Coastguard Worker
71*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
72*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/internal.h"
73*8fb009dcSAndroid Build Coastguard Worker
74*8fb009dcSAndroid Build Coastguard Worker
75*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_BEGIN
76*8fb009dcSAndroid Build Coastguard Worker
ssl_is_key_type_supported(int key_type)77*8fb009dcSAndroid Build Coastguard Worker bool ssl_is_key_type_supported(int key_type) {
78*8fb009dcSAndroid Build Coastguard Worker return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC ||
79*8fb009dcSAndroid Build Coastguard Worker key_type == EVP_PKEY_ED25519;
80*8fb009dcSAndroid Build Coastguard Worker }
81*8fb009dcSAndroid Build Coastguard Worker
82*8fb009dcSAndroid Build Coastguard Worker typedef struct {
83*8fb009dcSAndroid Build Coastguard Worker uint16_t sigalg;
84*8fb009dcSAndroid Build Coastguard Worker int pkey_type;
85*8fb009dcSAndroid Build Coastguard Worker int curve;
86*8fb009dcSAndroid Build Coastguard Worker const EVP_MD *(*digest_func)(void);
87*8fb009dcSAndroid Build Coastguard Worker bool is_rsa_pss;
88*8fb009dcSAndroid Build Coastguard Worker bool tls12_ok;
89*8fb009dcSAndroid Build Coastguard Worker bool tls13_ok;
90*8fb009dcSAndroid Build Coastguard Worker bool client_only;
91*8fb009dcSAndroid Build Coastguard Worker } SSL_SIGNATURE_ALGORITHM;
92*8fb009dcSAndroid Build Coastguard Worker
93*8fb009dcSAndroid Build Coastguard Worker static const SSL_SIGNATURE_ALGORITHM kSignatureAlgorithms[] = {
94*8fb009dcSAndroid Build Coastguard Worker // PKCS#1 v1.5 code points are only allowed in TLS 1.2.
95*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_MD5_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_md5_sha1,
96*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/false,
97*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
98*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_sha1,
99*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/false,
100*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
101*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256,
102*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/false,
103*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
104*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384,
105*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/false,
106*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
107*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512,
108*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/false,
109*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
110*8fb009dcSAndroid Build Coastguard Worker
111*8fb009dcSAndroid Build Coastguard Worker // Legacy PKCS#1 v1.5 code points are only allowed in TLS 1.3 and
112*8fb009dcSAndroid Build Coastguard Worker // client-only. See draft-ietf-tls-tls13-pkcs1-00.
113*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA256_LEGACY, EVP_PKEY_RSA, NID_undef, &EVP_sha256,
114*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/false, /*tls13_ok=*/true,
115*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/true},
116*8fb009dcSAndroid Build Coastguard Worker
117*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PSS_RSAE_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256,
118*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/true, /*tls12_ok=*/true, /*tls13_ok=*/true,
119*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
120*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PSS_RSAE_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384,
121*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/true, /*tls12_ok=*/true, /*tls13_ok=*/true,
122*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
123*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PSS_RSAE_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512,
124*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/true, /*tls12_ok=*/true, /*tls13_ok=*/true,
125*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
126*8fb009dcSAndroid Build Coastguard Worker
127*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SHA1, EVP_PKEY_EC, NID_undef, &EVP_sha1,
128*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/false,
129*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
130*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SECP256R1_SHA256, EVP_PKEY_EC, NID_X9_62_prime256v1,
131*8fb009dcSAndroid Build Coastguard Worker &EVP_sha256, /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/true,
132*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
133*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SECP384R1_SHA384, EVP_PKEY_EC, NID_secp384r1, &EVP_sha384,
134*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/true,
135*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
136*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SECP521R1_SHA512, EVP_PKEY_EC, NID_secp521r1, &EVP_sha512,
137*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/true,
138*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
139*8fb009dcSAndroid Build Coastguard Worker
140*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ED25519, EVP_PKEY_ED25519, NID_undef, nullptr,
141*8fb009dcSAndroid Build Coastguard Worker /*is_rsa_pss=*/false, /*tls12_ok=*/true, /*tls13_ok=*/true,
142*8fb009dcSAndroid Build Coastguard Worker /*client_only=*/false},
143*8fb009dcSAndroid Build Coastguard Worker };
144*8fb009dcSAndroid Build Coastguard Worker
get_signature_algorithm(uint16_t sigalg)145*8fb009dcSAndroid Build Coastguard Worker static const SSL_SIGNATURE_ALGORITHM *get_signature_algorithm(uint16_t sigalg) {
146*8fb009dcSAndroid Build Coastguard Worker for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kSignatureAlgorithms); i++) {
147*8fb009dcSAndroid Build Coastguard Worker if (kSignatureAlgorithms[i].sigalg == sigalg) {
148*8fb009dcSAndroid Build Coastguard Worker return &kSignatureAlgorithms[i];
149*8fb009dcSAndroid Build Coastguard Worker }
150*8fb009dcSAndroid Build Coastguard Worker }
151*8fb009dcSAndroid Build Coastguard Worker return NULL;
152*8fb009dcSAndroid Build Coastguard Worker }
153*8fb009dcSAndroid Build Coastguard Worker
ssl_pkey_supports_algorithm(const SSL * ssl,EVP_PKEY * pkey,uint16_t sigalg,bool is_verify)154*8fb009dcSAndroid Build Coastguard Worker bool ssl_pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey,
155*8fb009dcSAndroid Build Coastguard Worker uint16_t sigalg, bool is_verify) {
156*8fb009dcSAndroid Build Coastguard Worker const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
157*8fb009dcSAndroid Build Coastguard Worker if (alg == NULL || EVP_PKEY_id(pkey) != alg->pkey_type) {
158*8fb009dcSAndroid Build Coastguard Worker return false;
159*8fb009dcSAndroid Build Coastguard Worker }
160*8fb009dcSAndroid Build Coastguard Worker
161*8fb009dcSAndroid Build Coastguard Worker // Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
162*8fb009dcSAndroid Build Coastguard Worker // emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
163*8fb009dcSAndroid Build Coastguard Worker // hash in TLS. Reasonable RSA key sizes are large enough for the largest
164*8fb009dcSAndroid Build Coastguard Worker // defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too small for
165*8fb009dcSAndroid Build Coastguard Worker // SHA-512. 1024-bit RSA is sometimes used for test credentials, so check the
166*8fb009dcSAndroid Build Coastguard Worker // size so that we can fall back to another algorithm in that case.
167*8fb009dcSAndroid Build Coastguard Worker if (alg->is_rsa_pss &&
168*8fb009dcSAndroid Build Coastguard Worker (size_t)EVP_PKEY_size(pkey) < 2 * EVP_MD_size(alg->digest_func()) + 2) {
169*8fb009dcSAndroid Build Coastguard Worker return false;
170*8fb009dcSAndroid Build Coastguard Worker }
171*8fb009dcSAndroid Build Coastguard Worker
172*8fb009dcSAndroid Build Coastguard Worker if (ssl_protocol_version(ssl) < TLS1_2_VERSION) {
173*8fb009dcSAndroid Build Coastguard Worker // TLS 1.0 and 1.1 do not negotiate algorithms and always sign one of two
174*8fb009dcSAndroid Build Coastguard Worker // hardcoded algorithms.
175*8fb009dcSAndroid Build Coastguard Worker return sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 ||
176*8fb009dcSAndroid Build Coastguard Worker sigalg == SSL_SIGN_ECDSA_SHA1;
177*8fb009dcSAndroid Build Coastguard Worker }
178*8fb009dcSAndroid Build Coastguard Worker
179*8fb009dcSAndroid Build Coastguard Worker // |SSL_SIGN_RSA_PKCS1_MD5_SHA1| is not a real SignatureScheme for TLS 1.2 and
180*8fb009dcSAndroid Build Coastguard Worker // higher. It is an internal value we use to represent TLS 1.0/1.1's MD5/SHA1
181*8fb009dcSAndroid Build Coastguard Worker // concatenation.
182*8fb009dcSAndroid Build Coastguard Worker if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1) {
183*8fb009dcSAndroid Build Coastguard Worker return false;
184*8fb009dcSAndroid Build Coastguard Worker }
185*8fb009dcSAndroid Build Coastguard Worker
186*8fb009dcSAndroid Build Coastguard Worker if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
187*8fb009dcSAndroid Build Coastguard Worker if (!alg->tls13_ok) {
188*8fb009dcSAndroid Build Coastguard Worker return false;
189*8fb009dcSAndroid Build Coastguard Worker }
190*8fb009dcSAndroid Build Coastguard Worker
191*8fb009dcSAndroid Build Coastguard Worker bool is_client_sign = ssl->server == is_verify;
192*8fb009dcSAndroid Build Coastguard Worker if (alg->client_only && !is_client_sign) {
193*8fb009dcSAndroid Build Coastguard Worker return false;
194*8fb009dcSAndroid Build Coastguard Worker }
195*8fb009dcSAndroid Build Coastguard Worker
196*8fb009dcSAndroid Build Coastguard Worker // EC keys have a curve requirement.
197*8fb009dcSAndroid Build Coastguard Worker if (alg->pkey_type == EVP_PKEY_EC &&
198*8fb009dcSAndroid Build Coastguard Worker (alg->curve == NID_undef ||
199*8fb009dcSAndroid Build Coastguard Worker EC_GROUP_get_curve_name(
200*8fb009dcSAndroid Build Coastguard Worker EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey))) != alg->curve)) {
201*8fb009dcSAndroid Build Coastguard Worker return false;
202*8fb009dcSAndroid Build Coastguard Worker }
203*8fb009dcSAndroid Build Coastguard Worker } else if (!alg->tls12_ok) {
204*8fb009dcSAndroid Build Coastguard Worker return false;
205*8fb009dcSAndroid Build Coastguard Worker }
206*8fb009dcSAndroid Build Coastguard Worker
207*8fb009dcSAndroid Build Coastguard Worker return true;
208*8fb009dcSAndroid Build Coastguard Worker }
209*8fb009dcSAndroid Build Coastguard Worker
setup_ctx(SSL * ssl,EVP_MD_CTX * ctx,EVP_PKEY * pkey,uint16_t sigalg,bool is_verify)210*8fb009dcSAndroid Build Coastguard Worker static bool setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
211*8fb009dcSAndroid Build Coastguard Worker uint16_t sigalg, bool is_verify) {
212*8fb009dcSAndroid Build Coastguard Worker if (!ssl_pkey_supports_algorithm(ssl, pkey, sigalg, is_verify)) {
213*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
214*8fb009dcSAndroid Build Coastguard Worker return false;
215*8fb009dcSAndroid Build Coastguard Worker }
216*8fb009dcSAndroid Build Coastguard Worker
217*8fb009dcSAndroid Build Coastguard Worker const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
218*8fb009dcSAndroid Build Coastguard Worker const EVP_MD *digest = alg->digest_func != NULL ? alg->digest_func() : NULL;
219*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY_CTX *pctx;
220*8fb009dcSAndroid Build Coastguard Worker if (is_verify) {
221*8fb009dcSAndroid Build Coastguard Worker if (!EVP_DigestVerifyInit(ctx, &pctx, digest, NULL, pkey)) {
222*8fb009dcSAndroid Build Coastguard Worker return false;
223*8fb009dcSAndroid Build Coastguard Worker }
224*8fb009dcSAndroid Build Coastguard Worker } else if (!EVP_DigestSignInit(ctx, &pctx, digest, NULL, pkey)) {
225*8fb009dcSAndroid Build Coastguard Worker return false;
226*8fb009dcSAndroid Build Coastguard Worker }
227*8fb009dcSAndroid Build Coastguard Worker
228*8fb009dcSAndroid Build Coastguard Worker if (alg->is_rsa_pss) {
229*8fb009dcSAndroid Build Coastguard Worker if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
230*8fb009dcSAndroid Build Coastguard Worker !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) {
231*8fb009dcSAndroid Build Coastguard Worker return false;
232*8fb009dcSAndroid Build Coastguard Worker }
233*8fb009dcSAndroid Build Coastguard Worker }
234*8fb009dcSAndroid Build Coastguard Worker
235*8fb009dcSAndroid Build Coastguard Worker return true;
236*8fb009dcSAndroid Build Coastguard Worker }
237*8fb009dcSAndroid Build Coastguard Worker
ssl_private_key_sign(SSL_HANDSHAKE * hs,uint8_t * out,size_t * out_len,size_t max_out,uint16_t sigalg,Span<const uint8_t> in)238*8fb009dcSAndroid Build Coastguard Worker enum ssl_private_key_result_t ssl_private_key_sign(
239*8fb009dcSAndroid Build Coastguard Worker SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
240*8fb009dcSAndroid Build Coastguard Worker uint16_t sigalg, Span<const uint8_t> in) {
241*8fb009dcSAndroid Build Coastguard Worker SSL *const ssl = hs->ssl;
242*8fb009dcSAndroid Build Coastguard Worker const SSL_CREDENTIAL *const cred = hs->credential.get();
243*8fb009dcSAndroid Build Coastguard Worker SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
244*8fb009dcSAndroid Build Coastguard Worker Array<uint8_t> spki;
245*8fb009dcSAndroid Build Coastguard Worker if (hints) {
246*8fb009dcSAndroid Build Coastguard Worker ScopedCBB spki_cbb;
247*8fb009dcSAndroid Build Coastguard Worker if (!CBB_init(spki_cbb.get(), 64) ||
248*8fb009dcSAndroid Build Coastguard Worker !EVP_marshal_public_key(spki_cbb.get(), cred->pubkey.get()) ||
249*8fb009dcSAndroid Build Coastguard Worker !CBBFinishArray(spki_cbb.get(), &spki)) {
250*8fb009dcSAndroid Build Coastguard Worker ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
251*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_failure;
252*8fb009dcSAndroid Build Coastguard Worker }
253*8fb009dcSAndroid Build Coastguard Worker }
254*8fb009dcSAndroid Build Coastguard Worker
255*8fb009dcSAndroid Build Coastguard Worker // Replay the signature from handshake hints if available.
256*8fb009dcSAndroid Build Coastguard Worker if (hints && !hs->hints_requested && //
257*8fb009dcSAndroid Build Coastguard Worker sigalg == hints->signature_algorithm && //
258*8fb009dcSAndroid Build Coastguard Worker in == hints->signature_input &&
259*8fb009dcSAndroid Build Coastguard Worker MakeConstSpan(spki) == hints->signature_spki &&
260*8fb009dcSAndroid Build Coastguard Worker !hints->signature.empty() && //
261*8fb009dcSAndroid Build Coastguard Worker hints->signature.size() <= max_out) {
262*8fb009dcSAndroid Build Coastguard Worker // Signature algorithm and input both match. Reuse the signature from hints.
263*8fb009dcSAndroid Build Coastguard Worker *out_len = hints->signature.size();
264*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(out, hints->signature.data(), hints->signature.size());
265*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_success;
266*8fb009dcSAndroid Build Coastguard Worker }
267*8fb009dcSAndroid Build Coastguard Worker
268*8fb009dcSAndroid Build Coastguard Worker const SSL_PRIVATE_KEY_METHOD *key_method = cred->key_method;
269*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY *privkey = cred->privkey.get();
270*8fb009dcSAndroid Build Coastguard Worker assert(!hs->can_release_private_key);
271*8fb009dcSAndroid Build Coastguard Worker
272*8fb009dcSAndroid Build Coastguard Worker if (key_method != NULL) {
273*8fb009dcSAndroid Build Coastguard Worker enum ssl_private_key_result_t ret;
274*8fb009dcSAndroid Build Coastguard Worker if (hs->pending_private_key_op) {
275*8fb009dcSAndroid Build Coastguard Worker ret = key_method->complete(ssl, out, out_len, max_out);
276*8fb009dcSAndroid Build Coastguard Worker } else {
277*8fb009dcSAndroid Build Coastguard Worker ret = key_method->sign(ssl, out, out_len, max_out, sigalg, in.data(),
278*8fb009dcSAndroid Build Coastguard Worker in.size());
279*8fb009dcSAndroid Build Coastguard Worker }
280*8fb009dcSAndroid Build Coastguard Worker if (ret == ssl_private_key_failure) {
281*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
282*8fb009dcSAndroid Build Coastguard Worker }
283*8fb009dcSAndroid Build Coastguard Worker hs->pending_private_key_op = ret == ssl_private_key_retry;
284*8fb009dcSAndroid Build Coastguard Worker if (ret != ssl_private_key_success) {
285*8fb009dcSAndroid Build Coastguard Worker return ret;
286*8fb009dcSAndroid Build Coastguard Worker }
287*8fb009dcSAndroid Build Coastguard Worker } else {
288*8fb009dcSAndroid Build Coastguard Worker *out_len = max_out;
289*8fb009dcSAndroid Build Coastguard Worker ScopedEVP_MD_CTX ctx;
290*8fb009dcSAndroid Build Coastguard Worker if (!setup_ctx(ssl, ctx.get(), privkey, sigalg, false /* sign */) ||
291*8fb009dcSAndroid Build Coastguard Worker !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) {
292*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_failure;
293*8fb009dcSAndroid Build Coastguard Worker }
294*8fb009dcSAndroid Build Coastguard Worker }
295*8fb009dcSAndroid Build Coastguard Worker
296*8fb009dcSAndroid Build Coastguard Worker // Save the hint if applicable.
297*8fb009dcSAndroid Build Coastguard Worker if (hints && hs->hints_requested) {
298*8fb009dcSAndroid Build Coastguard Worker hints->signature_algorithm = sigalg;
299*8fb009dcSAndroid Build Coastguard Worker hints->signature_spki = std::move(spki);
300*8fb009dcSAndroid Build Coastguard Worker if (!hints->signature_input.CopyFrom(in) ||
301*8fb009dcSAndroid Build Coastguard Worker !hints->signature.CopyFrom(MakeConstSpan(out, *out_len))) {
302*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_failure;
303*8fb009dcSAndroid Build Coastguard Worker }
304*8fb009dcSAndroid Build Coastguard Worker }
305*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_success;
306*8fb009dcSAndroid Build Coastguard Worker }
307*8fb009dcSAndroid Build Coastguard Worker
ssl_public_key_verify(SSL * ssl,Span<const uint8_t> signature,uint16_t sigalg,EVP_PKEY * pkey,Span<const uint8_t> in)308*8fb009dcSAndroid Build Coastguard Worker bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature,
309*8fb009dcSAndroid Build Coastguard Worker uint16_t sigalg, EVP_PKEY *pkey,
310*8fb009dcSAndroid Build Coastguard Worker Span<const uint8_t> in) {
311*8fb009dcSAndroid Build Coastguard Worker ScopedEVP_MD_CTX ctx;
312*8fb009dcSAndroid Build Coastguard Worker if (!setup_ctx(ssl, ctx.get(), pkey, sigalg, true /* verify */)) {
313*8fb009dcSAndroid Build Coastguard Worker return false;
314*8fb009dcSAndroid Build Coastguard Worker }
315*8fb009dcSAndroid Build Coastguard Worker bool ok = EVP_DigestVerify(ctx.get(), signature.data(), signature.size(),
316*8fb009dcSAndroid Build Coastguard Worker in.data(), in.size());
317*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
318*8fb009dcSAndroid Build Coastguard Worker ok = true;
319*8fb009dcSAndroid Build Coastguard Worker ERR_clear_error();
320*8fb009dcSAndroid Build Coastguard Worker #endif
321*8fb009dcSAndroid Build Coastguard Worker return ok;
322*8fb009dcSAndroid Build Coastguard Worker }
323*8fb009dcSAndroid Build Coastguard Worker
ssl_private_key_decrypt(SSL_HANDSHAKE * hs,uint8_t * out,size_t * out_len,size_t max_out,Span<const uint8_t> in)324*8fb009dcSAndroid Build Coastguard Worker enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
325*8fb009dcSAndroid Build Coastguard Worker uint8_t *out,
326*8fb009dcSAndroid Build Coastguard Worker size_t *out_len,
327*8fb009dcSAndroid Build Coastguard Worker size_t max_out,
328*8fb009dcSAndroid Build Coastguard Worker Span<const uint8_t> in) {
329*8fb009dcSAndroid Build Coastguard Worker SSL *const ssl = hs->ssl;
330*8fb009dcSAndroid Build Coastguard Worker const SSL_CREDENTIAL *const cred = hs->credential.get();
331*8fb009dcSAndroid Build Coastguard Worker assert(!hs->can_release_private_key);
332*8fb009dcSAndroid Build Coastguard Worker if (cred->key_method != NULL) {
333*8fb009dcSAndroid Build Coastguard Worker enum ssl_private_key_result_t ret;
334*8fb009dcSAndroid Build Coastguard Worker if (hs->pending_private_key_op) {
335*8fb009dcSAndroid Build Coastguard Worker ret = cred->key_method->complete(ssl, out, out_len, max_out);
336*8fb009dcSAndroid Build Coastguard Worker } else {
337*8fb009dcSAndroid Build Coastguard Worker ret = cred->key_method->decrypt(ssl, out, out_len, max_out, in.data(),
338*8fb009dcSAndroid Build Coastguard Worker in.size());
339*8fb009dcSAndroid Build Coastguard Worker }
340*8fb009dcSAndroid Build Coastguard Worker if (ret == ssl_private_key_failure) {
341*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
342*8fb009dcSAndroid Build Coastguard Worker }
343*8fb009dcSAndroid Build Coastguard Worker hs->pending_private_key_op = ret == ssl_private_key_retry;
344*8fb009dcSAndroid Build Coastguard Worker return ret;
345*8fb009dcSAndroid Build Coastguard Worker }
346*8fb009dcSAndroid Build Coastguard Worker
347*8fb009dcSAndroid Build Coastguard Worker RSA *rsa = EVP_PKEY_get0_RSA(cred->privkey.get());
348*8fb009dcSAndroid Build Coastguard Worker if (rsa == NULL) {
349*8fb009dcSAndroid Build Coastguard Worker // Decrypt operations are only supported for RSA keys.
350*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
351*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_failure;
352*8fb009dcSAndroid Build Coastguard Worker }
353*8fb009dcSAndroid Build Coastguard Worker
354*8fb009dcSAndroid Build Coastguard Worker // Decrypt with no padding. PKCS#1 padding will be removed as part of the
355*8fb009dcSAndroid Build Coastguard Worker // timing-sensitive code by the caller.
356*8fb009dcSAndroid Build Coastguard Worker if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(),
357*8fb009dcSAndroid Build Coastguard Worker RSA_NO_PADDING)) {
358*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_failure;
359*8fb009dcSAndroid Build Coastguard Worker }
360*8fb009dcSAndroid Build Coastguard Worker return ssl_private_key_success;
361*8fb009dcSAndroid Build Coastguard Worker }
362*8fb009dcSAndroid Build Coastguard Worker
363*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_END
364*8fb009dcSAndroid Build Coastguard Worker
365*8fb009dcSAndroid Build Coastguard Worker using namespace bssl;
366*8fb009dcSAndroid Build Coastguard Worker
SSL_use_RSAPrivateKey(SSL * ssl,RSA * rsa)367*8fb009dcSAndroid Build Coastguard Worker int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
368*8fb009dcSAndroid Build Coastguard Worker if (rsa == NULL || ssl->config == NULL) {
369*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
370*8fb009dcSAndroid Build Coastguard Worker return 0;
371*8fb009dcSAndroid Build Coastguard Worker }
372*8fb009dcSAndroid Build Coastguard Worker
373*8fb009dcSAndroid Build Coastguard Worker UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
374*8fb009dcSAndroid Build Coastguard Worker if (!pkey ||
375*8fb009dcSAndroid Build Coastguard Worker !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
376*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
377*8fb009dcSAndroid Build Coastguard Worker return 0;
378*8fb009dcSAndroid Build Coastguard Worker }
379*8fb009dcSAndroid Build Coastguard Worker
380*8fb009dcSAndroid Build Coastguard Worker return SSL_use_PrivateKey(ssl, pkey.get());
381*8fb009dcSAndroid Build Coastguard Worker }
382*8fb009dcSAndroid Build Coastguard Worker
SSL_use_RSAPrivateKey_ASN1(SSL * ssl,const uint8_t * der,size_t der_len)383*8fb009dcSAndroid Build Coastguard Worker int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
384*8fb009dcSAndroid Build Coastguard Worker UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
385*8fb009dcSAndroid Build Coastguard Worker if (!rsa) {
386*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
387*8fb009dcSAndroid Build Coastguard Worker return 0;
388*8fb009dcSAndroid Build Coastguard Worker }
389*8fb009dcSAndroid Build Coastguard Worker
390*8fb009dcSAndroid Build Coastguard Worker return SSL_use_RSAPrivateKey(ssl, rsa.get());
391*8fb009dcSAndroid Build Coastguard Worker }
392*8fb009dcSAndroid Build Coastguard Worker
SSL_use_PrivateKey(SSL * ssl,EVP_PKEY * pkey)393*8fb009dcSAndroid Build Coastguard Worker int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
394*8fb009dcSAndroid Build Coastguard Worker if (pkey == NULL || ssl->config == NULL) {
395*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
396*8fb009dcSAndroid Build Coastguard Worker return 0;
397*8fb009dcSAndroid Build Coastguard Worker }
398*8fb009dcSAndroid Build Coastguard Worker
399*8fb009dcSAndroid Build Coastguard Worker return SSL_CREDENTIAL_set1_private_key(
400*8fb009dcSAndroid Build Coastguard Worker ssl->config->cert->default_credential.get(), pkey);
401*8fb009dcSAndroid Build Coastguard Worker }
402*8fb009dcSAndroid Build Coastguard Worker
SSL_use_PrivateKey_ASN1(int type,SSL * ssl,const uint8_t * der,size_t der_len)403*8fb009dcSAndroid Build Coastguard Worker int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
404*8fb009dcSAndroid Build Coastguard Worker size_t der_len) {
405*8fb009dcSAndroid Build Coastguard Worker if (der_len > LONG_MAX) {
406*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
407*8fb009dcSAndroid Build Coastguard Worker return 0;
408*8fb009dcSAndroid Build Coastguard Worker }
409*8fb009dcSAndroid Build Coastguard Worker
410*8fb009dcSAndroid Build Coastguard Worker const uint8_t *p = der;
411*8fb009dcSAndroid Build Coastguard Worker UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
412*8fb009dcSAndroid Build Coastguard Worker if (!pkey || p != der + der_len) {
413*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
414*8fb009dcSAndroid Build Coastguard Worker return 0;
415*8fb009dcSAndroid Build Coastguard Worker }
416*8fb009dcSAndroid Build Coastguard Worker
417*8fb009dcSAndroid Build Coastguard Worker return SSL_use_PrivateKey(ssl, pkey.get());
418*8fb009dcSAndroid Build Coastguard Worker }
419*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_use_RSAPrivateKey(SSL_CTX * ctx,RSA * rsa)420*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
421*8fb009dcSAndroid Build Coastguard Worker if (rsa == NULL) {
422*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
423*8fb009dcSAndroid Build Coastguard Worker return 0;
424*8fb009dcSAndroid Build Coastguard Worker }
425*8fb009dcSAndroid Build Coastguard Worker
426*8fb009dcSAndroid Build Coastguard Worker UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
427*8fb009dcSAndroid Build Coastguard Worker if (!pkey ||
428*8fb009dcSAndroid Build Coastguard Worker !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
429*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
430*8fb009dcSAndroid Build Coastguard Worker return 0;
431*8fb009dcSAndroid Build Coastguard Worker }
432*8fb009dcSAndroid Build Coastguard Worker
433*8fb009dcSAndroid Build Coastguard Worker return SSL_CTX_use_PrivateKey(ctx, pkey.get());
434*8fb009dcSAndroid Build Coastguard Worker }
435*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX * ctx,const uint8_t * der,size_t der_len)436*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
437*8fb009dcSAndroid Build Coastguard Worker size_t der_len) {
438*8fb009dcSAndroid Build Coastguard Worker UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
439*8fb009dcSAndroid Build Coastguard Worker if (!rsa) {
440*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
441*8fb009dcSAndroid Build Coastguard Worker return 0;
442*8fb009dcSAndroid Build Coastguard Worker }
443*8fb009dcSAndroid Build Coastguard Worker
444*8fb009dcSAndroid Build Coastguard Worker return SSL_CTX_use_RSAPrivateKey(ctx, rsa.get());
445*8fb009dcSAndroid Build Coastguard Worker }
446*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_use_PrivateKey(SSL_CTX * ctx,EVP_PKEY * pkey)447*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
448*8fb009dcSAndroid Build Coastguard Worker if (pkey == NULL) {
449*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
450*8fb009dcSAndroid Build Coastguard Worker return 0;
451*8fb009dcSAndroid Build Coastguard Worker }
452*8fb009dcSAndroid Build Coastguard Worker
453*8fb009dcSAndroid Build Coastguard Worker return SSL_CREDENTIAL_set1_private_key(ctx->cert->default_credential.get(),
454*8fb009dcSAndroid Build Coastguard Worker pkey);
455*8fb009dcSAndroid Build Coastguard Worker }
456*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_use_PrivateKey_ASN1(int type,SSL_CTX * ctx,const uint8_t * der,size_t der_len)457*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
458*8fb009dcSAndroid Build Coastguard Worker size_t der_len) {
459*8fb009dcSAndroid Build Coastguard Worker if (der_len > LONG_MAX) {
460*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
461*8fb009dcSAndroid Build Coastguard Worker return 0;
462*8fb009dcSAndroid Build Coastguard Worker }
463*8fb009dcSAndroid Build Coastguard Worker
464*8fb009dcSAndroid Build Coastguard Worker const uint8_t *p = der;
465*8fb009dcSAndroid Build Coastguard Worker UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
466*8fb009dcSAndroid Build Coastguard Worker if (!pkey || p != der + der_len) {
467*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
468*8fb009dcSAndroid Build Coastguard Worker return 0;
469*8fb009dcSAndroid Build Coastguard Worker }
470*8fb009dcSAndroid Build Coastguard Worker
471*8fb009dcSAndroid Build Coastguard Worker return SSL_CTX_use_PrivateKey(ctx, pkey.get());
472*8fb009dcSAndroid Build Coastguard Worker }
473*8fb009dcSAndroid Build Coastguard Worker
SSL_set_private_key_method(SSL * ssl,const SSL_PRIVATE_KEY_METHOD * key_method)474*8fb009dcSAndroid Build Coastguard Worker void SSL_set_private_key_method(SSL *ssl,
475*8fb009dcSAndroid Build Coastguard Worker const SSL_PRIVATE_KEY_METHOD *key_method) {
476*8fb009dcSAndroid Build Coastguard Worker if (!ssl->config) {
477*8fb009dcSAndroid Build Coastguard Worker return;
478*8fb009dcSAndroid Build Coastguard Worker }
479*8fb009dcSAndroid Build Coastguard Worker BSSL_CHECK(SSL_CREDENTIAL_set_private_key_method(
480*8fb009dcSAndroid Build Coastguard Worker ssl->config->cert->default_credential.get(), key_method));
481*8fb009dcSAndroid Build Coastguard Worker }
482*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_set_private_key_method(SSL_CTX * ctx,const SSL_PRIVATE_KEY_METHOD * key_method)483*8fb009dcSAndroid Build Coastguard Worker void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
484*8fb009dcSAndroid Build Coastguard Worker const SSL_PRIVATE_KEY_METHOD *key_method) {
485*8fb009dcSAndroid Build Coastguard Worker BSSL_CHECK(SSL_CREDENTIAL_set_private_key_method(
486*8fb009dcSAndroid Build Coastguard Worker ctx->cert->default_credential.get(), key_method));
487*8fb009dcSAndroid Build Coastguard Worker }
488*8fb009dcSAndroid Build Coastguard Worker
489*8fb009dcSAndroid Build Coastguard Worker static constexpr size_t kMaxSignatureAlgorithmNameLen = 24;
490*8fb009dcSAndroid Build Coastguard Worker
491*8fb009dcSAndroid Build Coastguard Worker struct SignatureAlgorithmName {
492*8fb009dcSAndroid Build Coastguard Worker uint16_t signature_algorithm;
493*8fb009dcSAndroid Build Coastguard Worker const char name[kMaxSignatureAlgorithmNameLen];
494*8fb009dcSAndroid Build Coastguard Worker };
495*8fb009dcSAndroid Build Coastguard Worker
496*8fb009dcSAndroid Build Coastguard Worker // This was "constexpr" rather than "const", but that triggered a bug in MSVC
497*8fb009dcSAndroid Build Coastguard Worker // where it didn't pad the strings to the correct length.
498*8fb009dcSAndroid Build Coastguard Worker static const SignatureAlgorithmName kSignatureAlgorithmNames[] = {
499*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_MD5_SHA1, "rsa_pkcs1_md5_sha1"},
500*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA1, "rsa_pkcs1_sha1"},
501*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA256, "rsa_pkcs1_sha256"},
502*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA256_LEGACY, "rsa_pkcs1_sha256_legacy"},
503*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA384, "rsa_pkcs1_sha384"},
504*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PKCS1_SHA512, "rsa_pkcs1_sha512"},
505*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SHA1, "ecdsa_sha1"},
506*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SECP256R1_SHA256, "ecdsa_secp256r1_sha256"},
507*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SECP384R1_SHA384, "ecdsa_secp384r1_sha384"},
508*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ECDSA_SECP521R1_SHA512, "ecdsa_secp521r1_sha512"},
509*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PSS_RSAE_SHA256, "rsa_pss_rsae_sha256"},
510*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PSS_RSAE_SHA384, "rsa_pss_rsae_sha384"},
511*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_RSA_PSS_RSAE_SHA512, "rsa_pss_rsae_sha512"},
512*8fb009dcSAndroid Build Coastguard Worker {SSL_SIGN_ED25519, "ed25519"},
513*8fb009dcSAndroid Build Coastguard Worker };
514*8fb009dcSAndroid Build Coastguard Worker
SSL_get_signature_algorithm_name(uint16_t sigalg,int include_curve)515*8fb009dcSAndroid Build Coastguard Worker const char *SSL_get_signature_algorithm_name(uint16_t sigalg,
516*8fb009dcSAndroid Build Coastguard Worker int include_curve) {
517*8fb009dcSAndroid Build Coastguard Worker if (!include_curve) {
518*8fb009dcSAndroid Build Coastguard Worker switch (sigalg) {
519*8fb009dcSAndroid Build Coastguard Worker case SSL_SIGN_ECDSA_SECP256R1_SHA256:
520*8fb009dcSAndroid Build Coastguard Worker return "ecdsa_sha256";
521*8fb009dcSAndroid Build Coastguard Worker case SSL_SIGN_ECDSA_SECP384R1_SHA384:
522*8fb009dcSAndroid Build Coastguard Worker return "ecdsa_sha384";
523*8fb009dcSAndroid Build Coastguard Worker case SSL_SIGN_ECDSA_SECP521R1_SHA512:
524*8fb009dcSAndroid Build Coastguard Worker return "ecdsa_sha512";
525*8fb009dcSAndroid Build Coastguard Worker // If adding more here, also update
526*8fb009dcSAndroid Build Coastguard Worker // |SSL_get_all_signature_algorithm_names|.
527*8fb009dcSAndroid Build Coastguard Worker }
528*8fb009dcSAndroid Build Coastguard Worker }
529*8fb009dcSAndroid Build Coastguard Worker
530*8fb009dcSAndroid Build Coastguard Worker for (const auto &candidate : kSignatureAlgorithmNames) {
531*8fb009dcSAndroid Build Coastguard Worker if (candidate.signature_algorithm == sigalg) {
532*8fb009dcSAndroid Build Coastguard Worker return candidate.name;
533*8fb009dcSAndroid Build Coastguard Worker }
534*8fb009dcSAndroid Build Coastguard Worker }
535*8fb009dcSAndroid Build Coastguard Worker
536*8fb009dcSAndroid Build Coastguard Worker return NULL;
537*8fb009dcSAndroid Build Coastguard Worker }
538*8fb009dcSAndroid Build Coastguard Worker
SSL_get_all_signature_algorithm_names(const char ** out,size_t max_out)539*8fb009dcSAndroid Build Coastguard Worker size_t SSL_get_all_signature_algorithm_names(const char **out, size_t max_out) {
540*8fb009dcSAndroid Build Coastguard Worker const char *kPredefinedNames[] = {"ecdsa_sha256", "ecdsa_sha384",
541*8fb009dcSAndroid Build Coastguard Worker "ecdsa_sha512"};
542*8fb009dcSAndroid Build Coastguard Worker return GetAllNames(out, max_out, MakeConstSpan(kPredefinedNames),
543*8fb009dcSAndroid Build Coastguard Worker &SignatureAlgorithmName::name,
544*8fb009dcSAndroid Build Coastguard Worker MakeConstSpan(kSignatureAlgorithmNames));
545*8fb009dcSAndroid Build Coastguard Worker }
546*8fb009dcSAndroid Build Coastguard Worker
SSL_get_signature_algorithm_key_type(uint16_t sigalg)547*8fb009dcSAndroid Build Coastguard Worker int SSL_get_signature_algorithm_key_type(uint16_t sigalg) {
548*8fb009dcSAndroid Build Coastguard Worker const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
549*8fb009dcSAndroid Build Coastguard Worker return alg != nullptr ? alg->pkey_type : EVP_PKEY_NONE;
550*8fb009dcSAndroid Build Coastguard Worker }
551*8fb009dcSAndroid Build Coastguard Worker
SSL_get_signature_algorithm_digest(uint16_t sigalg)552*8fb009dcSAndroid Build Coastguard Worker const EVP_MD *SSL_get_signature_algorithm_digest(uint16_t sigalg) {
553*8fb009dcSAndroid Build Coastguard Worker const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
554*8fb009dcSAndroid Build Coastguard Worker if (alg == nullptr || alg->digest_func == nullptr) {
555*8fb009dcSAndroid Build Coastguard Worker return nullptr;
556*8fb009dcSAndroid Build Coastguard Worker }
557*8fb009dcSAndroid Build Coastguard Worker return alg->digest_func();
558*8fb009dcSAndroid Build Coastguard Worker }
559*8fb009dcSAndroid Build Coastguard Worker
SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg)560*8fb009dcSAndroid Build Coastguard Worker int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) {
561*8fb009dcSAndroid Build Coastguard Worker const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
562*8fb009dcSAndroid Build Coastguard Worker return alg != nullptr && alg->is_rsa_pss;
563*8fb009dcSAndroid Build Coastguard Worker }
564*8fb009dcSAndroid Build Coastguard Worker
compare_uint16_t(const void * p1,const void * p2)565*8fb009dcSAndroid Build Coastguard Worker static int compare_uint16_t(const void *p1, const void *p2) {
566*8fb009dcSAndroid Build Coastguard Worker uint16_t u1 = *((const uint16_t *)p1);
567*8fb009dcSAndroid Build Coastguard Worker uint16_t u2 = *((const uint16_t *)p2);
568*8fb009dcSAndroid Build Coastguard Worker if (u1 < u2) {
569*8fb009dcSAndroid Build Coastguard Worker return -1;
570*8fb009dcSAndroid Build Coastguard Worker } else if (u1 > u2) {
571*8fb009dcSAndroid Build Coastguard Worker return 1;
572*8fb009dcSAndroid Build Coastguard Worker } else {
573*8fb009dcSAndroid Build Coastguard Worker return 0;
574*8fb009dcSAndroid Build Coastguard Worker }
575*8fb009dcSAndroid Build Coastguard Worker }
576*8fb009dcSAndroid Build Coastguard Worker
sigalgs_unique(Span<const uint16_t> in_sigalgs)577*8fb009dcSAndroid Build Coastguard Worker static bool sigalgs_unique(Span<const uint16_t> in_sigalgs) {
578*8fb009dcSAndroid Build Coastguard Worker if (in_sigalgs.size() < 2) {
579*8fb009dcSAndroid Build Coastguard Worker return true;
580*8fb009dcSAndroid Build Coastguard Worker }
581*8fb009dcSAndroid Build Coastguard Worker
582*8fb009dcSAndroid Build Coastguard Worker Array<uint16_t> sigalgs;
583*8fb009dcSAndroid Build Coastguard Worker if (!sigalgs.CopyFrom(in_sigalgs)) {
584*8fb009dcSAndroid Build Coastguard Worker return false;
585*8fb009dcSAndroid Build Coastguard Worker }
586*8fb009dcSAndroid Build Coastguard Worker
587*8fb009dcSAndroid Build Coastguard Worker qsort(sigalgs.data(), sigalgs.size(), sizeof(uint16_t), compare_uint16_t);
588*8fb009dcSAndroid Build Coastguard Worker
589*8fb009dcSAndroid Build Coastguard Worker for (size_t i = 1; i < sigalgs.size(); i++) {
590*8fb009dcSAndroid Build Coastguard Worker if (sigalgs[i - 1] == sigalgs[i]) {
591*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_SIGNATURE_ALGORITHM);
592*8fb009dcSAndroid Build Coastguard Worker return false;
593*8fb009dcSAndroid Build Coastguard Worker }
594*8fb009dcSAndroid Build Coastguard Worker }
595*8fb009dcSAndroid Build Coastguard Worker
596*8fb009dcSAndroid Build Coastguard Worker return true;
597*8fb009dcSAndroid Build Coastguard Worker }
598*8fb009dcSAndroid Build Coastguard Worker
set_sigalg_prefs(Array<uint16_t> * out,Span<const uint16_t> prefs)599*8fb009dcSAndroid Build Coastguard Worker static bool set_sigalg_prefs(Array<uint16_t> *out, Span<const uint16_t> prefs) {
600*8fb009dcSAndroid Build Coastguard Worker if (!sigalgs_unique(prefs)) {
601*8fb009dcSAndroid Build Coastguard Worker return false;
602*8fb009dcSAndroid Build Coastguard Worker }
603*8fb009dcSAndroid Build Coastguard Worker
604*8fb009dcSAndroid Build Coastguard Worker // Check for invalid algorithms, and filter out |SSL_SIGN_RSA_PKCS1_MD5_SHA1|.
605*8fb009dcSAndroid Build Coastguard Worker Array<uint16_t> filtered;
606*8fb009dcSAndroid Build Coastguard Worker if (!filtered.Init(prefs.size())) {
607*8fb009dcSAndroid Build Coastguard Worker return false;
608*8fb009dcSAndroid Build Coastguard Worker }
609*8fb009dcSAndroid Build Coastguard Worker size_t added = 0;
610*8fb009dcSAndroid Build Coastguard Worker for (uint16_t pref : prefs) {
611*8fb009dcSAndroid Build Coastguard Worker if (pref == SSL_SIGN_RSA_PKCS1_MD5_SHA1) {
612*8fb009dcSAndroid Build Coastguard Worker // Though not intended to be used with this API, we treat
613*8fb009dcSAndroid Build Coastguard Worker // |SSL_SIGN_RSA_PKCS1_MD5_SHA1| as a real signature algorithm in
614*8fb009dcSAndroid Build Coastguard Worker // |SSL_PRIVATE_KEY_METHOD|. Not accepting it here makes for a confusing
615*8fb009dcSAndroid Build Coastguard Worker // abstraction.
616*8fb009dcSAndroid Build Coastguard Worker continue;
617*8fb009dcSAndroid Build Coastguard Worker }
618*8fb009dcSAndroid Build Coastguard Worker if (get_signature_algorithm(pref) == nullptr) {
619*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
620*8fb009dcSAndroid Build Coastguard Worker return false;
621*8fb009dcSAndroid Build Coastguard Worker }
622*8fb009dcSAndroid Build Coastguard Worker filtered[added] = pref;
623*8fb009dcSAndroid Build Coastguard Worker added++;
624*8fb009dcSAndroid Build Coastguard Worker }
625*8fb009dcSAndroid Build Coastguard Worker filtered.Shrink(added);
626*8fb009dcSAndroid Build Coastguard Worker
627*8fb009dcSAndroid Build Coastguard Worker // This can happen if |prefs| contained only |SSL_SIGN_RSA_PKCS1_MD5_SHA1|.
628*8fb009dcSAndroid Build Coastguard Worker // Leaving it empty would revert to the default, so treat this as an error
629*8fb009dcSAndroid Build Coastguard Worker // condition.
630*8fb009dcSAndroid Build Coastguard Worker if (!prefs.empty() && filtered.empty()) {
631*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
632*8fb009dcSAndroid Build Coastguard Worker return false;
633*8fb009dcSAndroid Build Coastguard Worker }
634*8fb009dcSAndroid Build Coastguard Worker
635*8fb009dcSAndroid Build Coastguard Worker *out = std::move(filtered);
636*8fb009dcSAndroid Build Coastguard Worker return true;
637*8fb009dcSAndroid Build Coastguard Worker }
638*8fb009dcSAndroid Build Coastguard Worker
SSL_CREDENTIAL_set1_signing_algorithm_prefs(SSL_CREDENTIAL * cred,const uint16_t * prefs,size_t num_prefs)639*8fb009dcSAndroid Build Coastguard Worker int SSL_CREDENTIAL_set1_signing_algorithm_prefs(SSL_CREDENTIAL *cred,
640*8fb009dcSAndroid Build Coastguard Worker const uint16_t *prefs,
641*8fb009dcSAndroid Build Coastguard Worker size_t num_prefs) {
642*8fb009dcSAndroid Build Coastguard Worker if (!cred->UsesPrivateKey()) {
643*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
644*8fb009dcSAndroid Build Coastguard Worker return 0;
645*8fb009dcSAndroid Build Coastguard Worker }
646*8fb009dcSAndroid Build Coastguard Worker
647*8fb009dcSAndroid Build Coastguard Worker // Delegated credentials are constrained to a single algorithm, so there is no
648*8fb009dcSAndroid Build Coastguard Worker // need to configure this.
649*8fb009dcSAndroid Build Coastguard Worker if (cred->type == SSLCredentialType::kDelegated) {
650*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
651*8fb009dcSAndroid Build Coastguard Worker return 0;
652*8fb009dcSAndroid Build Coastguard Worker }
653*8fb009dcSAndroid Build Coastguard Worker
654*8fb009dcSAndroid Build Coastguard Worker return set_sigalg_prefs(&cred->sigalgs, MakeConstSpan(prefs, num_prefs));
655*8fb009dcSAndroid Build Coastguard Worker }
656*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_set_signing_algorithm_prefs(SSL_CTX * ctx,const uint16_t * prefs,size_t num_prefs)657*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
658*8fb009dcSAndroid Build Coastguard Worker size_t num_prefs) {
659*8fb009dcSAndroid Build Coastguard Worker return SSL_CREDENTIAL_set1_signing_algorithm_prefs(
660*8fb009dcSAndroid Build Coastguard Worker ctx->cert->default_credential.get(), prefs, num_prefs);
661*8fb009dcSAndroid Build Coastguard Worker }
662*8fb009dcSAndroid Build Coastguard Worker
SSL_set_signing_algorithm_prefs(SSL * ssl,const uint16_t * prefs,size_t num_prefs)663*8fb009dcSAndroid Build Coastguard Worker int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
664*8fb009dcSAndroid Build Coastguard Worker size_t num_prefs) {
665*8fb009dcSAndroid Build Coastguard Worker if (!ssl->config) {
666*8fb009dcSAndroid Build Coastguard Worker return 0;
667*8fb009dcSAndroid Build Coastguard Worker }
668*8fb009dcSAndroid Build Coastguard Worker return SSL_CREDENTIAL_set1_signing_algorithm_prefs(
669*8fb009dcSAndroid Build Coastguard Worker ssl->config->cert->default_credential.get(), prefs, num_prefs);
670*8fb009dcSAndroid Build Coastguard Worker }
671*8fb009dcSAndroid Build Coastguard Worker
672*8fb009dcSAndroid Build Coastguard Worker static constexpr struct {
673*8fb009dcSAndroid Build Coastguard Worker int pkey_type;
674*8fb009dcSAndroid Build Coastguard Worker int hash_nid;
675*8fb009dcSAndroid Build Coastguard Worker uint16_t signature_algorithm;
676*8fb009dcSAndroid Build Coastguard Worker } kSignatureAlgorithmsMapping[] = {
677*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_RSA, NID_sha1, SSL_SIGN_RSA_PKCS1_SHA1},
678*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_RSA, NID_sha256, SSL_SIGN_RSA_PKCS1_SHA256},
679*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_RSA, NID_sha384, SSL_SIGN_RSA_PKCS1_SHA384},
680*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_RSA, NID_sha512, SSL_SIGN_RSA_PKCS1_SHA512},
681*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_RSA_PSS, NID_sha256, SSL_SIGN_RSA_PSS_RSAE_SHA256},
682*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_RSA_PSS, NID_sha384, SSL_SIGN_RSA_PSS_RSAE_SHA384},
683*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_RSA_PSS, NID_sha512, SSL_SIGN_RSA_PSS_RSAE_SHA512},
684*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_EC, NID_sha1, SSL_SIGN_ECDSA_SHA1},
685*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_EC, NID_sha256, SSL_SIGN_ECDSA_SECP256R1_SHA256},
686*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_EC, NID_sha384, SSL_SIGN_ECDSA_SECP384R1_SHA384},
687*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_EC, NID_sha512, SSL_SIGN_ECDSA_SECP521R1_SHA512},
688*8fb009dcSAndroid Build Coastguard Worker {EVP_PKEY_ED25519, NID_undef, SSL_SIGN_ED25519},
689*8fb009dcSAndroid Build Coastguard Worker };
690*8fb009dcSAndroid Build Coastguard Worker
parse_sigalg_pairs(Array<uint16_t> * out,const int * values,size_t num_values)691*8fb009dcSAndroid Build Coastguard Worker static bool parse_sigalg_pairs(Array<uint16_t> *out, const int *values,
692*8fb009dcSAndroid Build Coastguard Worker size_t num_values) {
693*8fb009dcSAndroid Build Coastguard Worker if ((num_values & 1) == 1) {
694*8fb009dcSAndroid Build Coastguard Worker return false;
695*8fb009dcSAndroid Build Coastguard Worker }
696*8fb009dcSAndroid Build Coastguard Worker
697*8fb009dcSAndroid Build Coastguard Worker const size_t num_pairs = num_values / 2;
698*8fb009dcSAndroid Build Coastguard Worker if (!out->Init(num_pairs)) {
699*8fb009dcSAndroid Build Coastguard Worker return false;
700*8fb009dcSAndroid Build Coastguard Worker }
701*8fb009dcSAndroid Build Coastguard Worker
702*8fb009dcSAndroid Build Coastguard Worker for (size_t i = 0; i < num_values; i += 2) {
703*8fb009dcSAndroid Build Coastguard Worker const int hash_nid = values[i];
704*8fb009dcSAndroid Build Coastguard Worker const int pkey_type = values[i+1];
705*8fb009dcSAndroid Build Coastguard Worker
706*8fb009dcSAndroid Build Coastguard Worker bool found = false;
707*8fb009dcSAndroid Build Coastguard Worker for (const auto &candidate : kSignatureAlgorithmsMapping) {
708*8fb009dcSAndroid Build Coastguard Worker if (candidate.pkey_type == pkey_type && candidate.hash_nid == hash_nid) {
709*8fb009dcSAndroid Build Coastguard Worker (*out)[i / 2] = candidate.signature_algorithm;
710*8fb009dcSAndroid Build Coastguard Worker found = true;
711*8fb009dcSAndroid Build Coastguard Worker break;
712*8fb009dcSAndroid Build Coastguard Worker }
713*8fb009dcSAndroid Build Coastguard Worker }
714*8fb009dcSAndroid Build Coastguard Worker
715*8fb009dcSAndroid Build Coastguard Worker if (!found) {
716*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
717*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("unknown hash:%d pkey:%d", hash_nid, pkey_type);
718*8fb009dcSAndroid Build Coastguard Worker return false;
719*8fb009dcSAndroid Build Coastguard Worker }
720*8fb009dcSAndroid Build Coastguard Worker }
721*8fb009dcSAndroid Build Coastguard Worker
722*8fb009dcSAndroid Build Coastguard Worker return true;
723*8fb009dcSAndroid Build Coastguard Worker }
724*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_set1_sigalgs(SSL_CTX * ctx,const int * values,size_t num_values)725*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set1_sigalgs(SSL_CTX *ctx, const int *values, size_t num_values) {
726*8fb009dcSAndroid Build Coastguard Worker Array<uint16_t> sigalgs;
727*8fb009dcSAndroid Build Coastguard Worker if (!parse_sigalg_pairs(&sigalgs, values, num_values)) {
728*8fb009dcSAndroid Build Coastguard Worker return 0;
729*8fb009dcSAndroid Build Coastguard Worker }
730*8fb009dcSAndroid Build Coastguard Worker
731*8fb009dcSAndroid Build Coastguard Worker if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(),
732*8fb009dcSAndroid Build Coastguard Worker sigalgs.size()) ||
733*8fb009dcSAndroid Build Coastguard Worker !SSL_CTX_set_verify_algorithm_prefs(ctx, sigalgs.data(),
734*8fb009dcSAndroid Build Coastguard Worker sigalgs.size())) {
735*8fb009dcSAndroid Build Coastguard Worker return 0;
736*8fb009dcSAndroid Build Coastguard Worker }
737*8fb009dcSAndroid Build Coastguard Worker
738*8fb009dcSAndroid Build Coastguard Worker return 1;
739*8fb009dcSAndroid Build Coastguard Worker }
740*8fb009dcSAndroid Build Coastguard Worker
SSL_set1_sigalgs(SSL * ssl,const int * values,size_t num_values)741*8fb009dcSAndroid Build Coastguard Worker int SSL_set1_sigalgs(SSL *ssl, const int *values, size_t num_values) {
742*8fb009dcSAndroid Build Coastguard Worker if (!ssl->config) {
743*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
744*8fb009dcSAndroid Build Coastguard Worker return 0;
745*8fb009dcSAndroid Build Coastguard Worker }
746*8fb009dcSAndroid Build Coastguard Worker
747*8fb009dcSAndroid Build Coastguard Worker Array<uint16_t> sigalgs;
748*8fb009dcSAndroid Build Coastguard Worker if (!parse_sigalg_pairs(&sigalgs, values, num_values)) {
749*8fb009dcSAndroid Build Coastguard Worker return 0;
750*8fb009dcSAndroid Build Coastguard Worker }
751*8fb009dcSAndroid Build Coastguard Worker
752*8fb009dcSAndroid Build Coastguard Worker if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) ||
753*8fb009dcSAndroid Build Coastguard Worker !SSL_set_verify_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size())) {
754*8fb009dcSAndroid Build Coastguard Worker return 0;
755*8fb009dcSAndroid Build Coastguard Worker }
756*8fb009dcSAndroid Build Coastguard Worker
757*8fb009dcSAndroid Build Coastguard Worker return 1;
758*8fb009dcSAndroid Build Coastguard Worker }
759*8fb009dcSAndroid Build Coastguard Worker
parse_sigalgs_list(Array<uint16_t> * out,const char * str)760*8fb009dcSAndroid Build Coastguard Worker static bool parse_sigalgs_list(Array<uint16_t> *out, const char *str) {
761*8fb009dcSAndroid Build Coastguard Worker // str looks like "RSA+SHA1:ECDSA+SHA256:ecdsa_secp256r1_sha256".
762*8fb009dcSAndroid Build Coastguard Worker
763*8fb009dcSAndroid Build Coastguard Worker // Count colons to give the number of output elements from any successful
764*8fb009dcSAndroid Build Coastguard Worker // parse.
765*8fb009dcSAndroid Build Coastguard Worker size_t num_elements = 1;
766*8fb009dcSAndroid Build Coastguard Worker size_t len = 0;
767*8fb009dcSAndroid Build Coastguard Worker for (const char *p = str; *p; p++) {
768*8fb009dcSAndroid Build Coastguard Worker len++;
769*8fb009dcSAndroid Build Coastguard Worker if (*p == ':') {
770*8fb009dcSAndroid Build Coastguard Worker num_elements++;
771*8fb009dcSAndroid Build Coastguard Worker }
772*8fb009dcSAndroid Build Coastguard Worker }
773*8fb009dcSAndroid Build Coastguard Worker
774*8fb009dcSAndroid Build Coastguard Worker if (!out->Init(num_elements)) {
775*8fb009dcSAndroid Build Coastguard Worker return false;
776*8fb009dcSAndroid Build Coastguard Worker }
777*8fb009dcSAndroid Build Coastguard Worker size_t out_i = 0;
778*8fb009dcSAndroid Build Coastguard Worker
779*8fb009dcSAndroid Build Coastguard Worker enum {
780*8fb009dcSAndroid Build Coastguard Worker pkey_or_name,
781*8fb009dcSAndroid Build Coastguard Worker hash_name,
782*8fb009dcSAndroid Build Coastguard Worker } state = pkey_or_name;
783*8fb009dcSAndroid Build Coastguard Worker
784*8fb009dcSAndroid Build Coastguard Worker char buf[kMaxSignatureAlgorithmNameLen];
785*8fb009dcSAndroid Build Coastguard Worker // buf_used is always < sizeof(buf). I.e. it's always safe to write
786*8fb009dcSAndroid Build Coastguard Worker // buf[buf_used] = 0.
787*8fb009dcSAndroid Build Coastguard Worker size_t buf_used = 0;
788*8fb009dcSAndroid Build Coastguard Worker
789*8fb009dcSAndroid Build Coastguard Worker int pkey_type = 0, hash_nid = 0;
790*8fb009dcSAndroid Build Coastguard Worker
791*8fb009dcSAndroid Build Coastguard Worker // Note that the loop runs to len+1, i.e. it'll process the terminating NUL.
792*8fb009dcSAndroid Build Coastguard Worker for (size_t offset = 0; offset < len+1; offset++) {
793*8fb009dcSAndroid Build Coastguard Worker const unsigned char c = str[offset];
794*8fb009dcSAndroid Build Coastguard Worker
795*8fb009dcSAndroid Build Coastguard Worker switch (c) {
796*8fb009dcSAndroid Build Coastguard Worker case '+':
797*8fb009dcSAndroid Build Coastguard Worker if (state == hash_name) {
798*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
799*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("+ found in hash name at offset %zu", offset);
800*8fb009dcSAndroid Build Coastguard Worker return false;
801*8fb009dcSAndroid Build Coastguard Worker }
802*8fb009dcSAndroid Build Coastguard Worker if (buf_used == 0) {
803*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
804*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("empty public key type at offset %zu", offset);
805*8fb009dcSAndroid Build Coastguard Worker return false;
806*8fb009dcSAndroid Build Coastguard Worker }
807*8fb009dcSAndroid Build Coastguard Worker buf[buf_used] = 0;
808*8fb009dcSAndroid Build Coastguard Worker
809*8fb009dcSAndroid Build Coastguard Worker if (strcmp(buf, "RSA") == 0) {
810*8fb009dcSAndroid Build Coastguard Worker pkey_type = EVP_PKEY_RSA;
811*8fb009dcSAndroid Build Coastguard Worker } else if (strcmp(buf, "RSA-PSS") == 0 ||
812*8fb009dcSAndroid Build Coastguard Worker strcmp(buf, "PSS") == 0) {
813*8fb009dcSAndroid Build Coastguard Worker pkey_type = EVP_PKEY_RSA_PSS;
814*8fb009dcSAndroid Build Coastguard Worker } else if (strcmp(buf, "ECDSA") == 0) {
815*8fb009dcSAndroid Build Coastguard Worker pkey_type = EVP_PKEY_EC;
816*8fb009dcSAndroid Build Coastguard Worker } else {
817*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
818*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("unknown public key type '%s'", buf);
819*8fb009dcSAndroid Build Coastguard Worker return false;
820*8fb009dcSAndroid Build Coastguard Worker }
821*8fb009dcSAndroid Build Coastguard Worker
822*8fb009dcSAndroid Build Coastguard Worker state = hash_name;
823*8fb009dcSAndroid Build Coastguard Worker buf_used = 0;
824*8fb009dcSAndroid Build Coastguard Worker break;
825*8fb009dcSAndroid Build Coastguard Worker
826*8fb009dcSAndroid Build Coastguard Worker case ':':
827*8fb009dcSAndroid Build Coastguard Worker OPENSSL_FALLTHROUGH;
828*8fb009dcSAndroid Build Coastguard Worker case 0:
829*8fb009dcSAndroid Build Coastguard Worker if (buf_used == 0) {
830*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
831*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("empty element at offset %zu", offset);
832*8fb009dcSAndroid Build Coastguard Worker return false;
833*8fb009dcSAndroid Build Coastguard Worker }
834*8fb009dcSAndroid Build Coastguard Worker
835*8fb009dcSAndroid Build Coastguard Worker buf[buf_used] = 0;
836*8fb009dcSAndroid Build Coastguard Worker
837*8fb009dcSAndroid Build Coastguard Worker if (state == pkey_or_name) {
838*8fb009dcSAndroid Build Coastguard Worker // No '+' was seen thus this is a TLS 1.3-style name.
839*8fb009dcSAndroid Build Coastguard Worker bool found = false;
840*8fb009dcSAndroid Build Coastguard Worker for (const auto &candidate : kSignatureAlgorithmNames) {
841*8fb009dcSAndroid Build Coastguard Worker if (strcmp(candidate.name, buf) == 0) {
842*8fb009dcSAndroid Build Coastguard Worker assert(out_i < num_elements);
843*8fb009dcSAndroid Build Coastguard Worker (*out)[out_i++] = candidate.signature_algorithm;
844*8fb009dcSAndroid Build Coastguard Worker found = true;
845*8fb009dcSAndroid Build Coastguard Worker break;
846*8fb009dcSAndroid Build Coastguard Worker }
847*8fb009dcSAndroid Build Coastguard Worker }
848*8fb009dcSAndroid Build Coastguard Worker
849*8fb009dcSAndroid Build Coastguard Worker if (!found) {
850*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
851*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("unknown signature algorithm '%s'", buf);
852*8fb009dcSAndroid Build Coastguard Worker return false;
853*8fb009dcSAndroid Build Coastguard Worker }
854*8fb009dcSAndroid Build Coastguard Worker } else {
855*8fb009dcSAndroid Build Coastguard Worker if (strcmp(buf, "SHA1") == 0) {
856*8fb009dcSAndroid Build Coastguard Worker hash_nid = NID_sha1;
857*8fb009dcSAndroid Build Coastguard Worker } else if (strcmp(buf, "SHA256") == 0) {
858*8fb009dcSAndroid Build Coastguard Worker hash_nid = NID_sha256;
859*8fb009dcSAndroid Build Coastguard Worker } else if (strcmp(buf, "SHA384") == 0) {
860*8fb009dcSAndroid Build Coastguard Worker hash_nid = NID_sha384;
861*8fb009dcSAndroid Build Coastguard Worker } else if (strcmp(buf, "SHA512") == 0) {
862*8fb009dcSAndroid Build Coastguard Worker hash_nid = NID_sha512;
863*8fb009dcSAndroid Build Coastguard Worker } else {
864*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
865*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("unknown hash function '%s'", buf);
866*8fb009dcSAndroid Build Coastguard Worker return false;
867*8fb009dcSAndroid Build Coastguard Worker }
868*8fb009dcSAndroid Build Coastguard Worker
869*8fb009dcSAndroid Build Coastguard Worker bool found = false;
870*8fb009dcSAndroid Build Coastguard Worker for (const auto &candidate : kSignatureAlgorithmsMapping) {
871*8fb009dcSAndroid Build Coastguard Worker if (candidate.pkey_type == pkey_type &&
872*8fb009dcSAndroid Build Coastguard Worker candidate.hash_nid == hash_nid) {
873*8fb009dcSAndroid Build Coastguard Worker assert(out_i < num_elements);
874*8fb009dcSAndroid Build Coastguard Worker (*out)[out_i++] = candidate.signature_algorithm;
875*8fb009dcSAndroid Build Coastguard Worker found = true;
876*8fb009dcSAndroid Build Coastguard Worker break;
877*8fb009dcSAndroid Build Coastguard Worker }
878*8fb009dcSAndroid Build Coastguard Worker }
879*8fb009dcSAndroid Build Coastguard Worker
880*8fb009dcSAndroid Build Coastguard Worker if (!found) {
881*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
882*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("unknown pkey:%d hash:%s", pkey_type, buf);
883*8fb009dcSAndroid Build Coastguard Worker return false;
884*8fb009dcSAndroid Build Coastguard Worker }
885*8fb009dcSAndroid Build Coastguard Worker }
886*8fb009dcSAndroid Build Coastguard Worker
887*8fb009dcSAndroid Build Coastguard Worker state = pkey_or_name;
888*8fb009dcSAndroid Build Coastguard Worker buf_used = 0;
889*8fb009dcSAndroid Build Coastguard Worker break;
890*8fb009dcSAndroid Build Coastguard Worker
891*8fb009dcSAndroid Build Coastguard Worker default:
892*8fb009dcSAndroid Build Coastguard Worker if (buf_used == sizeof(buf) - 1) {
893*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
894*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("substring too long at offset %zu", offset);
895*8fb009dcSAndroid Build Coastguard Worker return false;
896*8fb009dcSAndroid Build Coastguard Worker }
897*8fb009dcSAndroid Build Coastguard Worker
898*8fb009dcSAndroid Build Coastguard Worker if (OPENSSL_isalnum(c) || c == '-' || c == '_') {
899*8fb009dcSAndroid Build Coastguard Worker buf[buf_used++] = c;
900*8fb009dcSAndroid Build Coastguard Worker } else {
901*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
902*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_dataf("invalid character 0x%02x at offest %zu", c,
903*8fb009dcSAndroid Build Coastguard Worker offset);
904*8fb009dcSAndroid Build Coastguard Worker return false;
905*8fb009dcSAndroid Build Coastguard Worker }
906*8fb009dcSAndroid Build Coastguard Worker }
907*8fb009dcSAndroid Build Coastguard Worker }
908*8fb009dcSAndroid Build Coastguard Worker
909*8fb009dcSAndroid Build Coastguard Worker assert(out_i == out->size());
910*8fb009dcSAndroid Build Coastguard Worker return true;
911*8fb009dcSAndroid Build Coastguard Worker }
912*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_set1_sigalgs_list(SSL_CTX * ctx,const char * str)913*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str) {
914*8fb009dcSAndroid Build Coastguard Worker Array<uint16_t> sigalgs;
915*8fb009dcSAndroid Build Coastguard Worker if (!parse_sigalgs_list(&sigalgs, str)) {
916*8fb009dcSAndroid Build Coastguard Worker return 0;
917*8fb009dcSAndroid Build Coastguard Worker }
918*8fb009dcSAndroid Build Coastguard Worker
919*8fb009dcSAndroid Build Coastguard Worker if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(),
920*8fb009dcSAndroid Build Coastguard Worker sigalgs.size()) ||
921*8fb009dcSAndroid Build Coastguard Worker !SSL_CTX_set_verify_algorithm_prefs(ctx, sigalgs.data(),
922*8fb009dcSAndroid Build Coastguard Worker sigalgs.size())) {
923*8fb009dcSAndroid Build Coastguard Worker return 0;
924*8fb009dcSAndroid Build Coastguard Worker }
925*8fb009dcSAndroid Build Coastguard Worker
926*8fb009dcSAndroid Build Coastguard Worker return 1;
927*8fb009dcSAndroid Build Coastguard Worker }
928*8fb009dcSAndroid Build Coastguard Worker
SSL_set1_sigalgs_list(SSL * ssl,const char * str)929*8fb009dcSAndroid Build Coastguard Worker int SSL_set1_sigalgs_list(SSL *ssl, const char *str) {
930*8fb009dcSAndroid Build Coastguard Worker if (!ssl->config) {
931*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
932*8fb009dcSAndroid Build Coastguard Worker return 0;
933*8fb009dcSAndroid Build Coastguard Worker }
934*8fb009dcSAndroid Build Coastguard Worker
935*8fb009dcSAndroid Build Coastguard Worker Array<uint16_t> sigalgs;
936*8fb009dcSAndroid Build Coastguard Worker if (!parse_sigalgs_list(&sigalgs, str)) {
937*8fb009dcSAndroid Build Coastguard Worker return 0;
938*8fb009dcSAndroid Build Coastguard Worker }
939*8fb009dcSAndroid Build Coastguard Worker
940*8fb009dcSAndroid Build Coastguard Worker if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) ||
941*8fb009dcSAndroid Build Coastguard Worker !SSL_set_verify_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size())) {
942*8fb009dcSAndroid Build Coastguard Worker return 0;
943*8fb009dcSAndroid Build Coastguard Worker }
944*8fb009dcSAndroid Build Coastguard Worker
945*8fb009dcSAndroid Build Coastguard Worker return 1;
946*8fb009dcSAndroid Build Coastguard Worker }
947*8fb009dcSAndroid Build Coastguard Worker
SSL_CTX_set_verify_algorithm_prefs(SSL_CTX * ctx,const uint16_t * prefs,size_t num_prefs)948*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
949*8fb009dcSAndroid Build Coastguard Worker size_t num_prefs) {
950*8fb009dcSAndroid Build Coastguard Worker return set_sigalg_prefs(&ctx->verify_sigalgs,
951*8fb009dcSAndroid Build Coastguard Worker MakeConstSpan(prefs, num_prefs));
952*8fb009dcSAndroid Build Coastguard Worker }
953*8fb009dcSAndroid Build Coastguard Worker
SSL_set_verify_algorithm_prefs(SSL * ssl,const uint16_t * prefs,size_t num_prefs)954*8fb009dcSAndroid Build Coastguard Worker int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
955*8fb009dcSAndroid Build Coastguard Worker size_t num_prefs) {
956*8fb009dcSAndroid Build Coastguard Worker if (!ssl->config) {
957*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
958*8fb009dcSAndroid Build Coastguard Worker return 0;
959*8fb009dcSAndroid Build Coastguard Worker }
960*8fb009dcSAndroid Build Coastguard Worker
961*8fb009dcSAndroid Build Coastguard Worker return set_sigalg_prefs(&ssl->config->verify_sigalgs,
962*8fb009dcSAndroid Build Coastguard Worker MakeConstSpan(prefs, num_prefs));
963*8fb009dcSAndroid Build Coastguard Worker }
964