blob: 876212dca9f40a856ad2762b35ad053e533ec1ad [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
David Benjamin443a1f62015-09-04 15:05:05 -040057#include <openssl/ssl.h>
Adam Langley95c29f32014-06-20 12:00:00 -070058
David Benjamin3a596112015-11-12 09:25:30 -080059#include <limits.h>
60
David Benjamin1fb125c2016-07-08 18:52:12 -070061#include <openssl/ec.h>
62#include <openssl/ec_key.h>
Adam Langley95c29f32014-06-20 12:00:00 -070063#include <openssl/err.h>
64#include <openssl/evp.h>
65#include <openssl/mem.h>
David Benjamind246b812016-07-08 15:07:02 -070066#include <openssl/type_check.h>
Adam Langley95c29f32014-06-20 12:00:00 -070067#include <openssl/x509.h>
David Benjamin34de91e2016-10-07 00:21:35 -040068#include <openssl/x509v3.h>
Adam Langley95c29f32014-06-20 12:00:00 -070069
David Benjamin2ee94aa2015-04-07 22:38:30 -040070#include "internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -070071
David Benjamin443a1f62015-09-04 15:05:05 -040072
Adam Langley95c29f32014-06-20 12:00:00 -070073static int ssl_set_cert(CERT *c, X509 *x509);
74static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
Adam Langley95c29f32014-06-20 12:00:00 -070075
David Benjamind1d80782015-07-05 11:54:09 -040076static int is_key_type_supported(int key_type) {
77 return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC;
78}
79
Adam Langleyfcf25832014-12-18 17:42:32 -080080int SSL_use_certificate(SSL *ssl, X509 *x) {
81 if (x == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -040082 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -080083 return 0;
84 }
Adam Langleyfcf25832014-12-18 17:42:32 -080085 return ssl_set_cert(ssl->cert, x);
86}
Adam Langley95c29f32014-06-20 12:00:00 -070087
David Benjamin3a596112015-11-12 09:25:30 -080088int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
89 if (der_len > LONG_MAX) {
90 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
Adam Langleyfcf25832014-12-18 17:42:32 -080091 return 0;
92 }
93
David Benjamin3a596112015-11-12 09:25:30 -080094 const uint8_t *p = der;
95 X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
96 if (x509 == NULL || p != der + der_len) {
97 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
98 X509_free(x509);
99 return 0;
100 }
101
102 int ret = SSL_use_certificate(ssl, x509);
103 X509_free(x509);
Adam Langleyfcf25832014-12-18 17:42:32 -0800104 return ret;
105}
106
107int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
108 EVP_PKEY *pkey;
109 int ret;
110
111 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400112 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800113 return 0;
114 }
115
Adam Langleyfcf25832014-12-18 17:42:32 -0800116 pkey = EVP_PKEY_new();
117 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400118 OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -0800119 return 0;
120 }
121
122 RSA_up_ref(rsa);
123 EVP_PKEY_assign_RSA(pkey, rsa);
124
125 ret = ssl_set_pkey(ssl->cert, pkey);
126 EVP_PKEY_free(pkey);
127
128 return ret;
129}
130
131static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) {
David Benjamind1d80782015-07-05 11:54:09 -0400132 if (!is_key_type_supported(pkey->type)) {
David Benjamin3570d732015-06-29 00:28:17 -0400133 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
Adam Langleyfcf25832014-12-18 17:42:32 -0800134 return 0;
135 }
136
Adam Langley3a2b47a2017-01-24 13:59:42 -0800137 if (c->chain != NULL &&
138 sk_CRYPTO_BUFFER_value(c->chain, 0) != NULL &&
139 /* Sanity-check that the private key and the certificate match, unless
140 * the key is opaque (in case of, say, a smartcard). */
141 !EVP_PKEY_is_opaque(pkey) &&
142 !ssl_cert_check_private_key(c, pkey)) {
143 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800144 }
145
David Benjamind1d80782015-07-05 11:54:09 -0400146 EVP_PKEY_free(c->privatekey);
Adam Langley310d3f62016-07-12 10:39:20 -0700147 EVP_PKEY_up_ref(pkey);
148 c->privatekey = pkey;
Adam Langleyfcf25832014-12-18 17:42:32 -0800149
150 return 1;
151}
152
Adam Langleyfcf25832014-12-18 17:42:32 -0800153int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800154 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400155 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800156 return 0;
157 }
158
Adam Langley3a2b47a2017-01-24 13:59:42 -0800159 return ssl_set_pkey(ssl->cert, pkey);
Adam Langleyfcf25832014-12-18 17:42:32 -0800160}
161
David Benjamin3a596112015-11-12 09:25:30 -0800162int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
163 size_t der_len) {
164 if (der_len > LONG_MAX) {
165 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
Adam Langleyfcf25832014-12-18 17:42:32 -0800166 return 0;
167 }
168
David Benjamin3a596112015-11-12 09:25:30 -0800169 const uint8_t *p = der;
170 EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
171 if (pkey == NULL || p != der + der_len) {
172 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
173 EVP_PKEY_free(pkey);
174 return 0;
175 }
176
177 int ret = SSL_use_PrivateKey(ssl, pkey);
Adam Langleyfcf25832014-12-18 17:42:32 -0800178 EVP_PKEY_free(pkey);
179 return ret;
180}
181
182int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
183 if (x == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400184 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800185 return 0;
186 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800187
188 return ssl_set_cert(ctx->cert, x);
189}
190
191static int ssl_set_cert(CERT *c, X509 *x) {
David Benjamind1d80782015-07-05 11:54:09 -0400192 EVP_PKEY *pkey = X509_get_pubkey(x);
Adam Langleyfcf25832014-12-18 17:42:32 -0800193 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400194 OPENSSL_PUT_ERROR(SSL, SSL_R_X509_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -0800195 return 0;
196 }
197
David Benjamind1d80782015-07-05 11:54:09 -0400198 if (!is_key_type_supported(pkey->type)) {
David Benjamin3570d732015-06-29 00:28:17 -0400199 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
Adam Langleyfcf25832014-12-18 17:42:32 -0800200 EVP_PKEY_free(pkey);
201 return 0;
202 }
203
David Benjamin34de91e2016-10-07 00:21:35 -0400204 /* An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
205 * certificates, so sanity-check the key usage extension. */
206 if (pkey->type == EVP_PKEY_EC) {
207 /* This call populates extension flags (ex_flags). */
208 X509_check_purpose(x, -1, 0);
209 if ((x->ex_flags & EXFLAG_KUSAGE) &&
210 !(x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
211 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
212 EVP_PKEY_free(pkey);
213 return 0;
214 }
215 }
216
David Benjamind1d80782015-07-05 11:54:09 -0400217 if (c->privatekey != NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800218 /* Sanity-check that the private key and the certificate match, unless the
219 * key is opaque (in case of, say, a smartcard). */
David Benjamind1d80782015-07-05 11:54:09 -0400220 if (!EVP_PKEY_is_opaque(c->privatekey) &&
221 !X509_check_private_key(x, c->privatekey)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800222 /* don't fail for a cert/key mismatch, just free current private key
223 * (when switching to a different cert & key, first this function should
224 * be used, then ssl_set_pkey */
David Benjamind1d80782015-07-05 11:54:09 -0400225 EVP_PKEY_free(c->privatekey);
226 c->privatekey = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -0800227 /* clear error queue */
228 ERR_clear_error();
229 }
230 }
231
232 EVP_PKEY_free(pkey);
233
Adam Langley3a2b47a2017-01-24 13:59:42 -0800234 CRYPTO_BUFFER *buffer = x509_to_buffer(x);
235 if (!buffer) {
236 return 0;
237 }
238
239 ssl_cert_flush_cached_x509_leaf(c);
240
241 if (c->chain != NULL) {
242 CRYPTO_BUFFER_free(sk_CRYPTO_BUFFER_value(c->chain, 0));
243 sk_CRYPTO_BUFFER_set(c->chain, 0, buffer);
244 return 1;
245 }
246
247 c->chain = sk_CRYPTO_BUFFER_new_null();
248 if (c->chain == NULL) {
249 CRYPTO_BUFFER_free(buffer);
250 return 0;
251 }
252
253 if (!sk_CRYPTO_BUFFER_push(c->chain, buffer)) {
254 CRYPTO_BUFFER_free(buffer);
255 sk_CRYPTO_BUFFER_free(c->chain);
256 c->chain = NULL;
257 return 0;
258 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800259
260 return 1;
261}
262
David Benjamin3a596112015-11-12 09:25:30 -0800263int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
264 const uint8_t *der) {
265 if (der_len > LONG_MAX) {
266 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
Adam Langleyfcf25832014-12-18 17:42:32 -0800267 return 0;
268 }
269
David Benjamin3a596112015-11-12 09:25:30 -0800270 const uint8_t *p = der;
271 X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
272 if (x509 == NULL || p != der + der_len) {
273 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
274 X509_free(x509);
275 return 0;
276 }
277
278 int ret = SSL_CTX_use_certificate(ctx, x509);
279 X509_free(x509);
Adam Langleyfcf25832014-12-18 17:42:32 -0800280 return ret;
281}
282
283int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
284 int ret;
285 EVP_PKEY *pkey;
286
287 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400288 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800289 return 0;
290 }
291
Adam Langleyfcf25832014-12-18 17:42:32 -0800292 pkey = EVP_PKEY_new();
293 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400294 OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -0800295 return 0;
296 }
297
298 RSA_up_ref(rsa);
299 EVP_PKEY_assign_RSA(pkey, rsa);
300
301 ret = ssl_set_pkey(ctx->cert, pkey);
302 EVP_PKEY_free(pkey);
303 return ret;
304}
305
David Benjamin74f71102015-06-27 14:56:25 -0400306int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
307 size_t der_len) {
308 RSA *rsa = RSA_private_key_from_bytes(der, der_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800309 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400310 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -0800311 return 0;
312 }
313
David Benjamin74f71102015-06-27 14:56:25 -0400314 int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
Adam Langleyfcf25832014-12-18 17:42:32 -0800315 RSA_free(rsa);
316 return ret;
317}
318
319int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
320 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400321 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800322 return 0;
323 }
324
Adam Langleyfcf25832014-12-18 17:42:32 -0800325 return ssl_set_pkey(ctx->cert, pkey);
326}
327
David Benjamin3a596112015-11-12 09:25:30 -0800328int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
329 size_t der_len) {
330 if (der_len > LONG_MAX) {
331 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
Adam Langleyfcf25832014-12-18 17:42:32 -0800332 return 0;
333 }
334
David Benjamin3a596112015-11-12 09:25:30 -0800335 const uint8_t *p = der;
336 EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
337 if (pkey == NULL || p != der + der_len) {
338 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
339 EVP_PKEY_free(pkey);
340 return 0;
341 }
342
343 int ret = SSL_CTX_use_PrivateKey(ctx, pkey);
Adam Langleyfcf25832014-12-18 17:42:32 -0800344 EVP_PKEY_free(pkey);
345 return ret;
346}
347
David Benjaminb4d65fd2015-05-29 17:11:21 -0400348void SSL_set_private_key_method(SSL *ssl,
349 const SSL_PRIVATE_KEY_METHOD *key_method) {
350 ssl->cert->key_method = key_method;
351}
352
Tom Thorogood66b2fe82016-03-06 20:08:38 +1030353void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
354 const SSL_PRIVATE_KEY_METHOD *key_method) {
355 ctx->cert->key_method = key_method;
356}
357
David Benjamin0fc37ef2016-08-17 15:29:46 -0400358static int set_signing_algorithm_prefs(CERT *cert, const uint16_t *prefs,
359 size_t num_prefs) {
Daniel Bathgate89917a52016-10-18 14:31:02 +0100360 OPENSSL_free(cert->sigalgs);
361
David Benjamin0fc37ef2016-08-17 15:29:46 -0400362 cert->num_sigalgs = 0;
363 cert->sigalgs = BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
364 if (cert->sigalgs == NULL) {
David Benjaminca3d5452016-07-14 12:51:01 -0400365 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
366 return 0;
367 }
David Benjamin0fc37ef2016-08-17 15:29:46 -0400368 cert->num_sigalgs = num_prefs;
David Benjaminca3d5452016-07-14 12:51:01 -0400369
370 return 1;
371}
372
David Benjamin0fc37ef2016-08-17 15:29:46 -0400373int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
374 size_t num_prefs) {
375 return set_signing_algorithm_prefs(ctx->cert, prefs, num_prefs);
376}
377
378
379int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
380 size_t num_prefs) {
381 return set_signing_algorithm_prefs(ssl->cert, prefs, num_prefs);
382}
383
Steven Valdez0d62f262015-09-04 12:41:04 -0400384int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
385 size_t num_digests) {
David Benjamind246b812016-07-08 15:07:02 -0700386 OPENSSL_free(ssl->cert->sigalgs);
Steven Valdez0d62f262015-09-04 12:41:04 -0400387
David Benjamin5db7c9b2017-01-24 16:17:03 -0500388 OPENSSL_COMPILE_ASSERT(sizeof(int) >= 2 * sizeof(uint16_t),
389 digest_list_conversion_cannot_overflow);
390
David Benjamin0fc37ef2016-08-17 15:29:46 -0400391 ssl->cert->num_sigalgs = 0;
David Benjamind246b812016-07-08 15:07:02 -0700392 ssl->cert->sigalgs = OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
393 if (ssl->cert->sigalgs == NULL) {
Steven Valdez0d62f262015-09-04 12:41:04 -0400394 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
395 return 0;
396 }
397
David Benjamind246b812016-07-08 15:07:02 -0700398 /* Convert the digest list to a signature algorithms list.
399 *
400 * TODO(davidben): Replace this API with one that can express RSA-PSS, etc. */
401 for (size_t i = 0; i < num_digests; i++) {
402 switch (digest_nids[i]) {
403 case NID_sha1:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400404 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1;
405 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1;
406 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700407 break;
408 case NID_sha256:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400409 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256;
410 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
David Benjamind246b812016-07-08 15:07:02 -0700411 SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -0400412 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700413 break;
414 case NID_sha384:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400415 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384;
416 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
David Benjamind246b812016-07-08 15:07:02 -0700417 SSL_SIGN_ECDSA_SECP384R1_SHA384;
David Benjamin0fc37ef2016-08-17 15:29:46 -0400418 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700419 break;
420 case NID_sha512:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400421 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512;
422 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
David Benjamind246b812016-07-08 15:07:02 -0700423 SSL_SIGN_ECDSA_SECP521R1_SHA512;
David Benjamin0fc37ef2016-08-17 15:29:46 -0400424 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700425 break;
426 }
427 }
428
Steven Valdez0d62f262015-09-04 12:41:04 -0400429 return 1;
430}
431
David Benjamin32a66d52016-07-13 22:03:11 -0400432int ssl_has_private_key(const SSL *ssl) {
nagendra modadugu601448a2015-07-24 09:31:31 -0700433 return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL;
434}
435
David Benjamin0c0b7e12016-07-14 13:47:55 -0400436int ssl_is_ecdsa_key_type(int type) {
437 switch (type) {
438 /* TODO(davidben): Remove support for |EVP_PKEY_EC| key types. */
439 case EVP_PKEY_EC:
440 case NID_X9_62_prime256v1:
441 case NID_secp384r1:
442 case NID_secp521r1:
443 return 1;
444 default:
445 return 0;
446 }
447}
448
David Benjamind1d80782015-07-05 11:54:09 -0400449int ssl_private_key_type(SSL *ssl) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400450 if (ssl->cert->key_method != NULL) {
451 return ssl->cert->key_method->type(ssl);
452 }
David Benjamin0c0b7e12016-07-14 13:47:55 -0400453 switch (EVP_PKEY_id(ssl->cert->privatekey)) {
454 case EVP_PKEY_RSA:
455 return NID_rsaEncryption;
456 case EVP_PKEY_EC:
457 return EC_GROUP_get_curve_name(
458 EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey)));
459 default:
460 return NID_undef;
461 }
David Benjaminb4d65fd2015-05-29 17:11:21 -0400462}
463
David Benjamind1d80782015-07-05 11:54:09 -0400464size_t ssl_private_key_max_signature_len(SSL *ssl) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400465 if (ssl->cert->key_method != NULL) {
466 return ssl->cert->key_method->max_signature_len(ssl);
467 }
David Benjamind1d80782015-07-05 11:54:09 -0400468 return EVP_PKEY_size(ssl->cert->privatekey);
David Benjaminb4d65fd2015-05-29 17:11:21 -0400469}
470
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400471/* TODO(davidben): Forbid RSA-PKCS1 in TLS 1.3. For now we allow it because NSS
472 * has yet to start doing RSA-PSS, so enforcing it would complicate interop
473 * testing. */
David Benjamina2d81f12016-07-08 15:42:16 -0700474static int is_rsa_pkcs1(const EVP_MD **out_md, uint16_t sigalg) {
475 switch (sigalg) {
476 case SSL_SIGN_RSA_PKCS1_MD5_SHA1:
477 *out_md = EVP_md5_sha1();
478 return 1;
479 case SSL_SIGN_RSA_PKCS1_SHA1:
480 *out_md = EVP_sha1();
481 return 1;
482 case SSL_SIGN_RSA_PKCS1_SHA256:
483 *out_md = EVP_sha256();
484 return 1;
485 case SSL_SIGN_RSA_PKCS1_SHA384:
486 *out_md = EVP_sha384();
487 return 1;
488 case SSL_SIGN_RSA_PKCS1_SHA512:
489 *out_md = EVP_sha512();
490 return 1;
David Benjamind246b812016-07-08 15:07:02 -0700491 default:
David Benjamina2d81f12016-07-08 15:42:16 -0700492 return 0;
David Benjamind246b812016-07-08 15:07:02 -0700493 }
494}
495
David Benjamina2d81f12016-07-08 15:42:16 -0700496static int ssl_sign_rsa_pkcs1(SSL *ssl, uint8_t *out, size_t *out_len,
497 size_t max_out, const EVP_MD *md,
498 const uint8_t *in, size_t in_len) {
499 EVP_MD_CTX ctx;
500 EVP_MD_CTX_init(&ctx);
501 *out_len = max_out;
502 int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
503 EVP_DigestSignUpdate(&ctx, in, in_len) &&
504 EVP_DigestSignFinal(&ctx, out, out_len);
505 EVP_MD_CTX_cleanup(&ctx);
506 return ret;
507}
508
509static int ssl_verify_rsa_pkcs1(SSL *ssl, const uint8_t *signature,
510 size_t signature_len, const EVP_MD *md,
511 EVP_PKEY *pkey, const uint8_t *in,
512 size_t in_len) {
David Benjamin887c3002016-07-08 16:15:32 -0700513 if (pkey->type != EVP_PKEY_RSA) {
514 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
515 return 0;
516 }
517
David Benjamina2d81f12016-07-08 15:42:16 -0700518 EVP_MD_CTX md_ctx;
519 EVP_MD_CTX_init(&md_ctx);
520 int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
521 EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
522 EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
523 EVP_MD_CTX_cleanup(&md_ctx);
524 return ret;
525}
526
David Benjamin1fb125c2016-07-08 18:52:12 -0700527static int is_ecdsa(int *out_curve, const EVP_MD **out_md, uint16_t sigalg) {
David Benjamina2d81f12016-07-08 15:42:16 -0700528 switch (sigalg) {
529 case SSL_SIGN_ECDSA_SHA1:
David Benjamin1fb125c2016-07-08 18:52:12 -0700530 *out_curve = NID_undef;
David Benjamina2d81f12016-07-08 15:42:16 -0700531 *out_md = EVP_sha1();
532 return 1;
533 case SSL_SIGN_ECDSA_SECP256R1_SHA256:
David Benjamin1fb125c2016-07-08 18:52:12 -0700534 *out_curve = NID_X9_62_prime256v1;
David Benjamina2d81f12016-07-08 15:42:16 -0700535 *out_md = EVP_sha256();
536 return 1;
537 case SSL_SIGN_ECDSA_SECP384R1_SHA384:
David Benjamin1fb125c2016-07-08 18:52:12 -0700538 *out_curve = NID_secp384r1;
David Benjamina2d81f12016-07-08 15:42:16 -0700539 *out_md = EVP_sha384();
540 return 1;
541 case SSL_SIGN_ECDSA_SECP521R1_SHA512:
David Benjamin1fb125c2016-07-08 18:52:12 -0700542 *out_curve = NID_secp521r1;
David Benjamina2d81f12016-07-08 15:42:16 -0700543 *out_md = EVP_sha512();
544 return 1;
545 default:
546 return 0;
547 }
548}
549
550static int ssl_sign_ecdsa(SSL *ssl, uint8_t *out, size_t *out_len,
David Benjamin1fb125c2016-07-08 18:52:12 -0700551 size_t max_out, int curve, const EVP_MD *md,
552 const uint8_t *in, size_t in_len) {
553 EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey);
554 if (ec_key == NULL) {
555 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
556 return 0;
557 }
558
559 /* In TLS 1.3, the curve is also specified by the signature algorithm. */
560 if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
561 (curve == NID_undef ||
562 EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) {
563 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
564 return 0;
565 }
566
David Benjamina2d81f12016-07-08 15:42:16 -0700567 EVP_MD_CTX ctx;
568 EVP_MD_CTX_init(&ctx);
569 *out_len = max_out;
570 int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
571 EVP_DigestSignUpdate(&ctx, in, in_len) &&
572 EVP_DigestSignFinal(&ctx, out, out_len);
573 EVP_MD_CTX_cleanup(&ctx);
574 return ret;
575}
576
577static int ssl_verify_ecdsa(SSL *ssl, const uint8_t *signature,
David Benjamin1fb125c2016-07-08 18:52:12 -0700578 size_t signature_len, int curve, const EVP_MD *md,
David Benjamina2d81f12016-07-08 15:42:16 -0700579 EVP_PKEY *pkey, const uint8_t *in, size_t in_len) {
David Benjamin1fb125c2016-07-08 18:52:12 -0700580 EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
581 if (ec_key == NULL) {
582 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
583 return 0;
584 }
585
586 /* In TLS 1.3, the curve is also specified by the signature algorithm. */
587 if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
588 (curve == NID_undef ||
589 EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) {
David Benjamin887c3002016-07-08 16:15:32 -0700590 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
591 return 0;
592 }
593
David Benjamina2d81f12016-07-08 15:42:16 -0700594 EVP_MD_CTX md_ctx;
595 EVP_MD_CTX_init(&md_ctx);
596 int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
597 EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
598 EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
599 EVP_MD_CTX_cleanup(&md_ctx);
600 return ret;
601}
602
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400603static int is_rsa_pss(const EVP_MD **out_md, uint16_t sigalg) {
604 switch (sigalg) {
605 case SSL_SIGN_RSA_PSS_SHA256:
606 *out_md = EVP_sha256();
607 return 1;
608 case SSL_SIGN_RSA_PSS_SHA384:
609 *out_md = EVP_sha384();
610 return 1;
611 case SSL_SIGN_RSA_PSS_SHA512:
612 *out_md = EVP_sha512();
613 return 1;
614 default:
615 return 0;
616 }
617}
618
619static int ssl_sign_rsa_pss(SSL *ssl, uint8_t *out, size_t *out_len,
620 size_t max_out, const EVP_MD *md,
621 const uint8_t *in, size_t in_len) {
622 EVP_MD_CTX ctx;
623 EVP_MD_CTX_init(&ctx);
624 *out_len = max_out;
625 EVP_PKEY_CTX *pctx;
626 int ret =
627 EVP_DigestSignInit(&ctx, &pctx, md, NULL, ssl->cert->privatekey) &&
628 EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) &&
629 EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) &&
630 EVP_DigestSignUpdate(&ctx, in, in_len) &&
631 EVP_DigestSignFinal(&ctx, out, out_len);
632 EVP_MD_CTX_cleanup(&ctx);
633 return ret;
634}
635
636static int ssl_verify_rsa_pss(SSL *ssl, const uint8_t *signature,
637 size_t signature_len, const EVP_MD *md,
638 EVP_PKEY *pkey, const uint8_t *in,
639 size_t in_len) {
640 if (pkey->type != EVP_PKEY_RSA) {
641 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
642 return 0;
643 }
644
645 EVP_MD_CTX md_ctx;
646 EVP_MD_CTX_init(&md_ctx);
647 EVP_PKEY_CTX *pctx;
648 int ret =
649 EVP_DigestVerifyInit(&md_ctx, &pctx, md, NULL, pkey) &&
650 EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) &&
651 EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) &&
652 EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
653 EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
654 EVP_MD_CTX_cleanup(&md_ctx);
655 return ret;
656}
657
David Benjaminb4d65fd2015-05-29 17:11:21 -0400658enum ssl_private_key_result_t ssl_private_key_sign(
Steven Valdezf0451ca2016-06-29 13:16:27 -0400659 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
660 uint16_t signature_algorithm, const uint8_t *in, size_t in_len) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400661 if (ssl->cert->key_method != NULL) {
David Benjamind3440b42016-07-14 14:52:41 -0400662 if (ssl->cert->key_method->sign != NULL) {
663 return ssl->cert->key_method->sign(ssl, out, out_len, max_out,
664 signature_algorithm, in, in_len);
665 }
666
667 /* TODO(davidben): Remove support for |sign_digest|-only
668 * |SSL_PRIVATE_KEY_METHOD|s. */
David Benjamina2d81f12016-07-08 15:42:16 -0700669 const EVP_MD *md;
David Benjamin1fb125c2016-07-08 18:52:12 -0700670 int curve;
David Benjamina2d81f12016-07-08 15:42:16 -0700671 if (!is_rsa_pkcs1(&md, signature_algorithm) &&
David Benjamin1fb125c2016-07-08 18:52:12 -0700672 !is_ecdsa(&curve, &md, signature_algorithm)) {
David Benjamina2d81f12016-07-08 15:42:16 -0700673 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY);
674 return ssl_private_key_failure;
675 }
676
677 uint8_t hash[EVP_MAX_MD_SIZE];
678 unsigned hash_len;
679 if (!EVP_Digest(in, in_len, hash, &hash_len, md, NULL)) {
680 return ssl_private_key_failure;
681 }
682
David Benjamind3440b42016-07-14 14:52:41 -0400683 return ssl->cert->key_method->sign_digest(ssl, out, out_len, max_out, md,
684 hash, hash_len);
David Benjaminb4d65fd2015-05-29 17:11:21 -0400685 }
686
David Benjamina2d81f12016-07-08 15:42:16 -0700687 const EVP_MD *md;
Steven Valdez54ed58e2016-08-18 14:03:49 -0400688 if (is_rsa_pkcs1(&md, signature_algorithm) &&
689 ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
David Benjamina2d81f12016-07-08 15:42:16 -0700690 return ssl_sign_rsa_pkcs1(ssl, out, out_len, max_out, md, in, in_len)
691 ? ssl_private_key_success
692 : ssl_private_key_failure;
693 }
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400694
David Benjamin1fb125c2016-07-08 18:52:12 -0700695 int curve;
696 if (is_ecdsa(&curve, &md, signature_algorithm)) {
697 return ssl_sign_ecdsa(ssl, out, out_len, max_out, curve, md, in, in_len)
David Benjamina2d81f12016-07-08 15:42:16 -0700698 ? ssl_private_key_success
699 : ssl_private_key_failure;
David Benjaminb4d65fd2015-05-29 17:11:21 -0400700 }
701
David Benjamin0e950152016-08-13 21:08:56 -0400702 if (is_rsa_pss(&md, signature_algorithm)) {
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400703 return ssl_sign_rsa_pss(ssl, out, out_len, max_out, md, in, in_len)
704 ? ssl_private_key_success
705 : ssl_private_key_failure;
706 }
707
David Benjamina2d81f12016-07-08 15:42:16 -0700708 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
709 return ssl_private_key_failure;
David Benjaminb4d65fd2015-05-29 17:11:21 -0400710}
711
Steven Valdez2b8415e2016-06-30 13:27:23 -0400712int ssl_public_key_verify(SSL *ssl, const uint8_t *signature,
713 size_t signature_len, uint16_t signature_algorithm,
714 EVP_PKEY *pkey, const uint8_t *in, size_t in_len) {
David Benjamina2d81f12016-07-08 15:42:16 -0700715 const EVP_MD *md;
Steven Valdez54ed58e2016-08-18 14:03:49 -0400716 if (is_rsa_pkcs1(&md, signature_algorithm) &&
717 ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
David Benjamina2d81f12016-07-08 15:42:16 -0700718 return ssl_verify_rsa_pkcs1(ssl, signature, signature_len, md, pkey, in,
719 in_len);
720 }
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400721
David Benjamin1fb125c2016-07-08 18:52:12 -0700722 int curve;
723 if (is_ecdsa(&curve, &md, signature_algorithm)) {
724 return ssl_verify_ecdsa(ssl, signature, signature_len, curve, md, pkey, in,
David Benjamina2d81f12016-07-08 15:42:16 -0700725 in_len);
Steven Valdez2b8415e2016-06-30 13:27:23 -0400726 }
727
David Benjamin0e950152016-08-13 21:08:56 -0400728 if (is_rsa_pss(&md, signature_algorithm)) {
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400729 return ssl_verify_rsa_pss(ssl, signature, signature_len, md, pkey, in,
730 in_len);
731 }
732
David Benjamina2d81f12016-07-08 15:42:16 -0700733 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
734 return 0;
Steven Valdez2b8415e2016-06-30 13:27:23 -0400735}
736
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700737enum ssl_private_key_result_t ssl_private_key_decrypt(
738 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
739 const uint8_t *in, size_t in_len) {
740 if (ssl->cert->key_method != NULL) {
741 return ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in,
742 in_len);
743 }
744
David Benjamin758d1272015-11-20 17:47:25 -0500745 RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey);
746 if (rsa == NULL) {
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700747 /* Decrypt operations are only supported for RSA keys. */
748 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
749 return ssl_private_key_failure;
750 }
751
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700752 /* Decrypt with no padding. PKCS#1 padding will be removed as part
753 * of the timing-sensitive code by the caller. */
David Benjamin758d1272015-11-20 17:47:25 -0500754 if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
755 return ssl_private_key_failure;
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700756 }
David Benjamin758d1272015-11-20 17:47:25 -0500757 return ssl_private_key_success;
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700758}
759
David Benjamind3440b42016-07-14 14:52:41 -0400760enum ssl_private_key_result_t ssl_private_key_complete(SSL *ssl, uint8_t *out,
761 size_t *out_len,
762 size_t max_out) {
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700763 /* Only custom keys may be asynchronous. */
David Benjamind3440b42016-07-14 14:52:41 -0400764 return ssl->cert->key_method->complete(ssl, out, out_len, max_out);
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700765}
David Benjamin1fb125c2016-07-08 18:52:12 -0700766
767int ssl_private_key_supports_signature_algorithm(SSL *ssl,
768 uint16_t signature_algorithm) {
769 const EVP_MD *md;
Steven Valdez54ed58e2016-08-18 14:03:49 -0400770 if (is_rsa_pkcs1(&md, signature_algorithm) &&
771 ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
David Benjamin0c0b7e12016-07-14 13:47:55 -0400772 return ssl_private_key_type(ssl) == NID_rsaEncryption;
David Benjamin1fb125c2016-07-08 18:52:12 -0700773 }
774
775 int curve;
776 if (is_ecdsa(&curve, &md, signature_algorithm)) {
David Benjamin0c0b7e12016-07-14 13:47:55 -0400777 int type = ssl_private_key_type(ssl);
778 if (!ssl_is_ecdsa_key_type(type)) {
David Benjamin1fb125c2016-07-08 18:52:12 -0700779 return 0;
780 }
781
David Benjamin0c0b7e12016-07-14 13:47:55 -0400782 /* Prior to TLS 1.3, ECDSA curves did not match the signature algorithm. */
783 if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
784 return 1;
David Benjamin1fb125c2016-07-08 18:52:12 -0700785 }
David Benjamin0c0b7e12016-07-14 13:47:55 -0400786
David Benjamin04fe9012016-09-23 14:49:42 -0400787 return curve != NID_undef && type == curve;
David Benjamin1fb125c2016-07-08 18:52:12 -0700788 }
789
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400790 if (is_rsa_pss(&md, signature_algorithm)) {
David Benjamin0e950152016-08-13 21:08:56 -0400791 if (ssl_private_key_type(ssl) != NID_rsaEncryption) {
David Benjamin7944a9f2016-07-12 22:27:01 -0400792 return 0;
793 }
794
795 /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
796 * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
797 * hash in TLS. Reasonable RSA key sizes are large enough for the largest
798 * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for
799 * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check
800 * the size to fall back to another algorithm. */
801 if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) {
802 return 0;
803 }
804
David Benjamind3440b42016-07-14 14:52:41 -0400805 /* RSA-PSS is only supported by message-based private keys. */
806 if (ssl->cert->key_method != NULL && ssl->cert->key_method->sign == NULL) {
807 return 0;
808 }
809
David Benjamin7944a9f2016-07-12 22:27:01 -0400810 return 1;
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400811 }
812
David Benjamin1fb125c2016-07-08 18:52:12 -0700813 return 0;
814}