blob: 34d1f8603d8ffc0093ebc608a4a9fd6c684d5ac5 [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 Langleyc5ac2b62016-11-07 12:02:35 -0800137 X509 *x509_leaf = c->x509_leaf;
138 if (x509_leaf != NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800139 /* Sanity-check that the private key and the certificate match, unless the
140 * key is opaque (in case of, say, a smartcard). */
141 if (!EVP_PKEY_is_opaque(pkey) &&
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800142 !X509_check_private_key(x509_leaf, pkey)) {
143 X509_free(c->x509_leaf);
144 c->x509_leaf = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -0800145 return 0;
146 }
147 }
148
David Benjamind1d80782015-07-05 11:54:09 -0400149 EVP_PKEY_free(c->privatekey);
Adam Langley310d3f62016-07-12 10:39:20 -0700150 EVP_PKEY_up_ref(pkey);
151 c->privatekey = pkey;
Adam Langleyfcf25832014-12-18 17:42:32 -0800152
153 return 1;
154}
155
Adam Langleyfcf25832014-12-18 17:42:32 -0800156int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
157 int ret;
158
159 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400160 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800161 return 0;
162 }
163
Adam Langleyfcf25832014-12-18 17:42:32 -0800164 ret = ssl_set_pkey(ssl->cert, pkey);
165 return ret;
166}
167
David Benjamin3a596112015-11-12 09:25:30 -0800168int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
169 size_t der_len) {
170 if (der_len > LONG_MAX) {
171 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
Adam Langleyfcf25832014-12-18 17:42:32 -0800172 return 0;
173 }
174
David Benjamin3a596112015-11-12 09:25:30 -0800175 const uint8_t *p = der;
176 EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
177 if (pkey == NULL || p != der + der_len) {
178 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
179 EVP_PKEY_free(pkey);
180 return 0;
181 }
182
183 int ret = SSL_use_PrivateKey(ssl, pkey);
Adam Langleyfcf25832014-12-18 17:42:32 -0800184 EVP_PKEY_free(pkey);
185 return ret;
186}
187
188int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
189 if (x == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400190 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800191 return 0;
192 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800193
194 return ssl_set_cert(ctx->cert, x);
195}
196
197static int ssl_set_cert(CERT *c, X509 *x) {
David Benjamind1d80782015-07-05 11:54:09 -0400198 EVP_PKEY *pkey = X509_get_pubkey(x);
Adam Langleyfcf25832014-12-18 17:42:32 -0800199 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400200 OPENSSL_PUT_ERROR(SSL, SSL_R_X509_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -0800201 return 0;
202 }
203
David Benjamind1d80782015-07-05 11:54:09 -0400204 if (!is_key_type_supported(pkey->type)) {
David Benjamin3570d732015-06-29 00:28:17 -0400205 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
Adam Langleyfcf25832014-12-18 17:42:32 -0800206 EVP_PKEY_free(pkey);
207 return 0;
208 }
209
David Benjamin34de91e2016-10-07 00:21:35 -0400210 /* An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
211 * certificates, so sanity-check the key usage extension. */
212 if (pkey->type == EVP_PKEY_EC) {
213 /* This call populates extension flags (ex_flags). */
214 X509_check_purpose(x, -1, 0);
215 if ((x->ex_flags & EXFLAG_KUSAGE) &&
216 !(x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
217 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
218 EVP_PKEY_free(pkey);
219 return 0;
220 }
221 }
222
David Benjamind1d80782015-07-05 11:54:09 -0400223 if (c->privatekey != NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800224 /* Sanity-check that the private key and the certificate match, unless the
225 * key is opaque (in case of, say, a smartcard). */
David Benjamind1d80782015-07-05 11:54:09 -0400226 if (!EVP_PKEY_is_opaque(c->privatekey) &&
227 !X509_check_private_key(x, c->privatekey)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800228 /* don't fail for a cert/key mismatch, just free current private key
229 * (when switching to a different cert & key, first this function should
230 * be used, then ssl_set_pkey */
David Benjamind1d80782015-07-05 11:54:09 -0400231 EVP_PKEY_free(c->privatekey);
232 c->privatekey = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -0800233 /* clear error queue */
234 ERR_clear_error();
235 }
236 }
237
238 EVP_PKEY_free(pkey);
239
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800240 X509_free(c->x509_leaf);
David Benjamin96a16cd2016-08-11 12:14:47 -0400241 X509_up_ref(x);
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800242 c->x509_leaf = x;
Adam Langleyfcf25832014-12-18 17:42:32 -0800243
244 return 1;
245}
246
David Benjamin3a596112015-11-12 09:25:30 -0800247int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
248 const uint8_t *der) {
249 if (der_len > LONG_MAX) {
250 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
Adam Langleyfcf25832014-12-18 17:42:32 -0800251 return 0;
252 }
253
David Benjamin3a596112015-11-12 09:25:30 -0800254 const uint8_t *p = der;
255 X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
256 if (x509 == NULL || p != der + der_len) {
257 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
258 X509_free(x509);
259 return 0;
260 }
261
262 int ret = SSL_CTX_use_certificate(ctx, x509);
263 X509_free(x509);
Adam Langleyfcf25832014-12-18 17:42:32 -0800264 return ret;
265}
266
267int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
268 int ret;
269 EVP_PKEY *pkey;
270
271 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400272 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800273 return 0;
274 }
275
Adam Langleyfcf25832014-12-18 17:42:32 -0800276 pkey = EVP_PKEY_new();
277 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400278 OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -0800279 return 0;
280 }
281
282 RSA_up_ref(rsa);
283 EVP_PKEY_assign_RSA(pkey, rsa);
284
285 ret = ssl_set_pkey(ctx->cert, pkey);
286 EVP_PKEY_free(pkey);
287 return ret;
288}
289
David Benjamin74f71102015-06-27 14:56:25 -0400290int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
291 size_t der_len) {
292 RSA *rsa = RSA_private_key_from_bytes(der, der_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800293 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400294 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -0800295 return 0;
296 }
297
David Benjamin74f71102015-06-27 14:56:25 -0400298 int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
Adam Langleyfcf25832014-12-18 17:42:32 -0800299 RSA_free(rsa);
300 return ret;
301}
302
303int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
304 if (pkey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400305 OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyfcf25832014-12-18 17:42:32 -0800306 return 0;
307 }
308
Adam Langleyfcf25832014-12-18 17:42:32 -0800309 return ssl_set_pkey(ctx->cert, pkey);
310}
311
David Benjamin3a596112015-11-12 09:25:30 -0800312int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
313 size_t der_len) {
314 if (der_len > LONG_MAX) {
315 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
Adam Langleyfcf25832014-12-18 17:42:32 -0800316 return 0;
317 }
318
David Benjamin3a596112015-11-12 09:25:30 -0800319 const uint8_t *p = der;
320 EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
321 if (pkey == NULL || p != der + der_len) {
322 OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
323 EVP_PKEY_free(pkey);
324 return 0;
325 }
326
327 int ret = SSL_CTX_use_PrivateKey(ctx, pkey);
Adam Langleyfcf25832014-12-18 17:42:32 -0800328 EVP_PKEY_free(pkey);
329 return ret;
330}
331
David Benjaminb4d65fd2015-05-29 17:11:21 -0400332void SSL_set_private_key_method(SSL *ssl,
333 const SSL_PRIVATE_KEY_METHOD *key_method) {
334 ssl->cert->key_method = key_method;
335}
336
Tom Thorogood66b2fe82016-03-06 20:08:38 +1030337void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
338 const SSL_PRIVATE_KEY_METHOD *key_method) {
339 ctx->cert->key_method = key_method;
340}
341
David Benjamin0fc37ef2016-08-17 15:29:46 -0400342static int set_signing_algorithm_prefs(CERT *cert, const uint16_t *prefs,
343 size_t num_prefs) {
Daniel Bathgate89917a52016-10-18 14:31:02 +0100344 OPENSSL_free(cert->sigalgs);
345
David Benjamin0fc37ef2016-08-17 15:29:46 -0400346 cert->num_sigalgs = 0;
347 cert->sigalgs = BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
348 if (cert->sigalgs == NULL) {
David Benjaminca3d5452016-07-14 12:51:01 -0400349 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
350 return 0;
351 }
David Benjamin0fc37ef2016-08-17 15:29:46 -0400352 cert->num_sigalgs = num_prefs;
David Benjaminca3d5452016-07-14 12:51:01 -0400353
354 return 1;
355}
356
David Benjamin0fc37ef2016-08-17 15:29:46 -0400357int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
358 size_t num_prefs) {
359 return set_signing_algorithm_prefs(ctx->cert, prefs, num_prefs);
360}
361
362
363int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
364 size_t num_prefs) {
365 return set_signing_algorithm_prefs(ssl->cert, prefs, num_prefs);
366}
367
Steven Valdez0d62f262015-09-04 12:41:04 -0400368int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
369 size_t num_digests) {
David Benjamind246b812016-07-08 15:07:02 -0700370 OPENSSL_free(ssl->cert->sigalgs);
Steven Valdez0d62f262015-09-04 12:41:04 -0400371
David Benjamin5db7c9b2017-01-24 16:17:03 -0500372 OPENSSL_COMPILE_ASSERT(sizeof(int) >= 2 * sizeof(uint16_t),
373 digest_list_conversion_cannot_overflow);
374
David Benjamin0fc37ef2016-08-17 15:29:46 -0400375 ssl->cert->num_sigalgs = 0;
David Benjamind246b812016-07-08 15:07:02 -0700376 ssl->cert->sigalgs = OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
377 if (ssl->cert->sigalgs == NULL) {
Steven Valdez0d62f262015-09-04 12:41:04 -0400378 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
379 return 0;
380 }
381
David Benjamind246b812016-07-08 15:07:02 -0700382 /* Convert the digest list to a signature algorithms list.
383 *
384 * TODO(davidben): Replace this API with one that can express RSA-PSS, etc. */
385 for (size_t i = 0; i < num_digests; i++) {
386 switch (digest_nids[i]) {
387 case NID_sha1:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400388 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1;
389 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1;
390 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700391 break;
392 case NID_sha256:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400393 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256;
394 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
David Benjamind246b812016-07-08 15:07:02 -0700395 SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -0400396 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700397 break;
398 case NID_sha384:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400399 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384;
400 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
David Benjamind246b812016-07-08 15:07:02 -0700401 SSL_SIGN_ECDSA_SECP384R1_SHA384;
David Benjamin0fc37ef2016-08-17 15:29:46 -0400402 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700403 break;
404 case NID_sha512:
David Benjamin0fc37ef2016-08-17 15:29:46 -0400405 ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512;
406 ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
David Benjamind246b812016-07-08 15:07:02 -0700407 SSL_SIGN_ECDSA_SECP521R1_SHA512;
David Benjamin0fc37ef2016-08-17 15:29:46 -0400408 ssl->cert->num_sigalgs += 2;
David Benjamind246b812016-07-08 15:07:02 -0700409 break;
410 }
411 }
412
Steven Valdez0d62f262015-09-04 12:41:04 -0400413 return 1;
414}
415
David Benjamin32a66d52016-07-13 22:03:11 -0400416int ssl_has_private_key(const SSL *ssl) {
nagendra modadugu601448a2015-07-24 09:31:31 -0700417 return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL;
418}
419
David Benjamin0c0b7e12016-07-14 13:47:55 -0400420int ssl_is_ecdsa_key_type(int type) {
421 switch (type) {
422 /* TODO(davidben): Remove support for |EVP_PKEY_EC| key types. */
423 case EVP_PKEY_EC:
424 case NID_X9_62_prime256v1:
425 case NID_secp384r1:
426 case NID_secp521r1:
427 return 1;
428 default:
429 return 0;
430 }
431}
432
David Benjamind1d80782015-07-05 11:54:09 -0400433int ssl_private_key_type(SSL *ssl) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400434 if (ssl->cert->key_method != NULL) {
435 return ssl->cert->key_method->type(ssl);
436 }
David Benjamin0c0b7e12016-07-14 13:47:55 -0400437 switch (EVP_PKEY_id(ssl->cert->privatekey)) {
438 case EVP_PKEY_RSA:
439 return NID_rsaEncryption;
440 case EVP_PKEY_EC:
441 return EC_GROUP_get_curve_name(
442 EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey)));
443 default:
444 return NID_undef;
445 }
David Benjaminb4d65fd2015-05-29 17:11:21 -0400446}
447
David Benjamind1d80782015-07-05 11:54:09 -0400448size_t ssl_private_key_max_signature_len(SSL *ssl) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400449 if (ssl->cert->key_method != NULL) {
450 return ssl->cert->key_method->max_signature_len(ssl);
451 }
David Benjamind1d80782015-07-05 11:54:09 -0400452 return EVP_PKEY_size(ssl->cert->privatekey);
David Benjaminb4d65fd2015-05-29 17:11:21 -0400453}
454
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400455/* TODO(davidben): Forbid RSA-PKCS1 in TLS 1.3. For now we allow it because NSS
456 * has yet to start doing RSA-PSS, so enforcing it would complicate interop
457 * testing. */
David Benjamina2d81f12016-07-08 15:42:16 -0700458static int is_rsa_pkcs1(const EVP_MD **out_md, uint16_t sigalg) {
459 switch (sigalg) {
460 case SSL_SIGN_RSA_PKCS1_MD5_SHA1:
461 *out_md = EVP_md5_sha1();
462 return 1;
463 case SSL_SIGN_RSA_PKCS1_SHA1:
464 *out_md = EVP_sha1();
465 return 1;
466 case SSL_SIGN_RSA_PKCS1_SHA256:
467 *out_md = EVP_sha256();
468 return 1;
469 case SSL_SIGN_RSA_PKCS1_SHA384:
470 *out_md = EVP_sha384();
471 return 1;
472 case SSL_SIGN_RSA_PKCS1_SHA512:
473 *out_md = EVP_sha512();
474 return 1;
David Benjamind246b812016-07-08 15:07:02 -0700475 default:
David Benjamina2d81f12016-07-08 15:42:16 -0700476 return 0;
David Benjamind246b812016-07-08 15:07:02 -0700477 }
478}
479
David Benjamina2d81f12016-07-08 15:42:16 -0700480static int ssl_sign_rsa_pkcs1(SSL *ssl, uint8_t *out, size_t *out_len,
481 size_t max_out, const EVP_MD *md,
482 const uint8_t *in, size_t in_len) {
483 EVP_MD_CTX ctx;
484 EVP_MD_CTX_init(&ctx);
485 *out_len = max_out;
486 int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
487 EVP_DigestSignUpdate(&ctx, in, in_len) &&
488 EVP_DigestSignFinal(&ctx, out, out_len);
489 EVP_MD_CTX_cleanup(&ctx);
490 return ret;
491}
492
493static int ssl_verify_rsa_pkcs1(SSL *ssl, const uint8_t *signature,
494 size_t signature_len, const EVP_MD *md,
495 EVP_PKEY *pkey, const uint8_t *in,
496 size_t in_len) {
David Benjamin887c3002016-07-08 16:15:32 -0700497 if (pkey->type != EVP_PKEY_RSA) {
498 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
499 return 0;
500 }
501
David Benjamina2d81f12016-07-08 15:42:16 -0700502 EVP_MD_CTX md_ctx;
503 EVP_MD_CTX_init(&md_ctx);
504 int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
505 EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
506 EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
507 EVP_MD_CTX_cleanup(&md_ctx);
508 return ret;
509}
510
David Benjamin1fb125c2016-07-08 18:52:12 -0700511static int is_ecdsa(int *out_curve, const EVP_MD **out_md, uint16_t sigalg) {
David Benjamina2d81f12016-07-08 15:42:16 -0700512 switch (sigalg) {
513 case SSL_SIGN_ECDSA_SHA1:
David Benjamin1fb125c2016-07-08 18:52:12 -0700514 *out_curve = NID_undef;
David Benjamina2d81f12016-07-08 15:42:16 -0700515 *out_md = EVP_sha1();
516 return 1;
517 case SSL_SIGN_ECDSA_SECP256R1_SHA256:
David Benjamin1fb125c2016-07-08 18:52:12 -0700518 *out_curve = NID_X9_62_prime256v1;
David Benjamina2d81f12016-07-08 15:42:16 -0700519 *out_md = EVP_sha256();
520 return 1;
521 case SSL_SIGN_ECDSA_SECP384R1_SHA384:
David Benjamin1fb125c2016-07-08 18:52:12 -0700522 *out_curve = NID_secp384r1;
David Benjamina2d81f12016-07-08 15:42:16 -0700523 *out_md = EVP_sha384();
524 return 1;
525 case SSL_SIGN_ECDSA_SECP521R1_SHA512:
David Benjamin1fb125c2016-07-08 18:52:12 -0700526 *out_curve = NID_secp521r1;
David Benjamina2d81f12016-07-08 15:42:16 -0700527 *out_md = EVP_sha512();
528 return 1;
529 default:
530 return 0;
531 }
532}
533
534static int ssl_sign_ecdsa(SSL *ssl, uint8_t *out, size_t *out_len,
David Benjamin1fb125c2016-07-08 18:52:12 -0700535 size_t max_out, int curve, const EVP_MD *md,
536 const uint8_t *in, size_t in_len) {
537 EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey);
538 if (ec_key == NULL) {
539 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
540 return 0;
541 }
542
543 /* In TLS 1.3, the curve is also specified by the signature algorithm. */
544 if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
545 (curve == NID_undef ||
546 EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) {
547 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
548 return 0;
549 }
550
David Benjamina2d81f12016-07-08 15:42:16 -0700551 EVP_MD_CTX ctx;
552 EVP_MD_CTX_init(&ctx);
553 *out_len = max_out;
554 int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
555 EVP_DigestSignUpdate(&ctx, in, in_len) &&
556 EVP_DigestSignFinal(&ctx, out, out_len);
557 EVP_MD_CTX_cleanup(&ctx);
558 return ret;
559}
560
561static int ssl_verify_ecdsa(SSL *ssl, const uint8_t *signature,
David Benjamin1fb125c2016-07-08 18:52:12 -0700562 size_t signature_len, int curve, const EVP_MD *md,
David Benjamina2d81f12016-07-08 15:42:16 -0700563 EVP_PKEY *pkey, const uint8_t *in, size_t in_len) {
David Benjamin1fb125c2016-07-08 18:52:12 -0700564 EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
565 if (ec_key == NULL) {
566 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
567 return 0;
568 }
569
570 /* In TLS 1.3, the curve is also specified by the signature algorithm. */
571 if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
572 (curve == NID_undef ||
573 EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) {
David Benjamin887c3002016-07-08 16:15:32 -0700574 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
575 return 0;
576 }
577
David Benjamina2d81f12016-07-08 15:42:16 -0700578 EVP_MD_CTX md_ctx;
579 EVP_MD_CTX_init(&md_ctx);
580 int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
581 EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
582 EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
583 EVP_MD_CTX_cleanup(&md_ctx);
584 return ret;
585}
586
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400587static int is_rsa_pss(const EVP_MD **out_md, uint16_t sigalg) {
588 switch (sigalg) {
589 case SSL_SIGN_RSA_PSS_SHA256:
590 *out_md = EVP_sha256();
591 return 1;
592 case SSL_SIGN_RSA_PSS_SHA384:
593 *out_md = EVP_sha384();
594 return 1;
595 case SSL_SIGN_RSA_PSS_SHA512:
596 *out_md = EVP_sha512();
597 return 1;
598 default:
599 return 0;
600 }
601}
602
603static int ssl_sign_rsa_pss(SSL *ssl, uint8_t *out, size_t *out_len,
604 size_t max_out, const EVP_MD *md,
605 const uint8_t *in, size_t in_len) {
606 EVP_MD_CTX ctx;
607 EVP_MD_CTX_init(&ctx);
608 *out_len = max_out;
609 EVP_PKEY_CTX *pctx;
610 int ret =
611 EVP_DigestSignInit(&ctx, &pctx, md, NULL, ssl->cert->privatekey) &&
612 EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) &&
613 EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) &&
614 EVP_DigestSignUpdate(&ctx, in, in_len) &&
615 EVP_DigestSignFinal(&ctx, out, out_len);
616 EVP_MD_CTX_cleanup(&ctx);
617 return ret;
618}
619
620static int ssl_verify_rsa_pss(SSL *ssl, const uint8_t *signature,
621 size_t signature_len, const EVP_MD *md,
622 EVP_PKEY *pkey, const uint8_t *in,
623 size_t in_len) {
624 if (pkey->type != EVP_PKEY_RSA) {
625 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
626 return 0;
627 }
628
629 EVP_MD_CTX md_ctx;
630 EVP_MD_CTX_init(&md_ctx);
631 EVP_PKEY_CTX *pctx;
632 int ret =
633 EVP_DigestVerifyInit(&md_ctx, &pctx, md, NULL, pkey) &&
634 EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) &&
635 EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) &&
636 EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
637 EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
638 EVP_MD_CTX_cleanup(&md_ctx);
639 return ret;
640}
641
David Benjaminb4d65fd2015-05-29 17:11:21 -0400642enum ssl_private_key_result_t ssl_private_key_sign(
Steven Valdezf0451ca2016-06-29 13:16:27 -0400643 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
644 uint16_t signature_algorithm, const uint8_t *in, size_t in_len) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400645 if (ssl->cert->key_method != NULL) {
David Benjamind3440b42016-07-14 14:52:41 -0400646 if (ssl->cert->key_method->sign != NULL) {
647 return ssl->cert->key_method->sign(ssl, out, out_len, max_out,
648 signature_algorithm, in, in_len);
649 }
650
651 /* TODO(davidben): Remove support for |sign_digest|-only
652 * |SSL_PRIVATE_KEY_METHOD|s. */
David Benjamina2d81f12016-07-08 15:42:16 -0700653 const EVP_MD *md;
David Benjamin1fb125c2016-07-08 18:52:12 -0700654 int curve;
David Benjamina2d81f12016-07-08 15:42:16 -0700655 if (!is_rsa_pkcs1(&md, signature_algorithm) &&
David Benjamin1fb125c2016-07-08 18:52:12 -0700656 !is_ecdsa(&curve, &md, signature_algorithm)) {
David Benjamina2d81f12016-07-08 15:42:16 -0700657 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY);
658 return ssl_private_key_failure;
659 }
660
661 uint8_t hash[EVP_MAX_MD_SIZE];
662 unsigned hash_len;
663 if (!EVP_Digest(in, in_len, hash, &hash_len, md, NULL)) {
664 return ssl_private_key_failure;
665 }
666
David Benjamind3440b42016-07-14 14:52:41 -0400667 return ssl->cert->key_method->sign_digest(ssl, out, out_len, max_out, md,
668 hash, hash_len);
David Benjaminb4d65fd2015-05-29 17:11:21 -0400669 }
670
David Benjamina2d81f12016-07-08 15:42:16 -0700671 const EVP_MD *md;
Steven Valdez54ed58e2016-08-18 14:03:49 -0400672 if (is_rsa_pkcs1(&md, signature_algorithm) &&
673 ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
David Benjamina2d81f12016-07-08 15:42:16 -0700674 return ssl_sign_rsa_pkcs1(ssl, out, out_len, max_out, md, in, in_len)
675 ? ssl_private_key_success
676 : ssl_private_key_failure;
677 }
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400678
David Benjamin1fb125c2016-07-08 18:52:12 -0700679 int curve;
680 if (is_ecdsa(&curve, &md, signature_algorithm)) {
681 return ssl_sign_ecdsa(ssl, out, out_len, max_out, curve, md, in, in_len)
David Benjamina2d81f12016-07-08 15:42:16 -0700682 ? ssl_private_key_success
683 : ssl_private_key_failure;
David Benjaminb4d65fd2015-05-29 17:11:21 -0400684 }
685
David Benjamin0e950152016-08-13 21:08:56 -0400686 if (is_rsa_pss(&md, signature_algorithm)) {
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400687 return ssl_sign_rsa_pss(ssl, out, out_len, max_out, md, in, in_len)
688 ? ssl_private_key_success
689 : ssl_private_key_failure;
690 }
691
David Benjamina2d81f12016-07-08 15:42:16 -0700692 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
693 return ssl_private_key_failure;
David Benjaminb4d65fd2015-05-29 17:11:21 -0400694}
695
Steven Valdez2b8415e2016-06-30 13:27:23 -0400696int ssl_public_key_verify(SSL *ssl, const uint8_t *signature,
697 size_t signature_len, uint16_t signature_algorithm,
698 EVP_PKEY *pkey, const uint8_t *in, size_t in_len) {
David Benjamina2d81f12016-07-08 15:42:16 -0700699 const EVP_MD *md;
Steven Valdez54ed58e2016-08-18 14:03:49 -0400700 if (is_rsa_pkcs1(&md, signature_algorithm) &&
701 ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
David Benjamina2d81f12016-07-08 15:42:16 -0700702 return ssl_verify_rsa_pkcs1(ssl, signature, signature_len, md, pkey, in,
703 in_len);
704 }
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400705
David Benjamin1fb125c2016-07-08 18:52:12 -0700706 int curve;
707 if (is_ecdsa(&curve, &md, signature_algorithm)) {
708 return ssl_verify_ecdsa(ssl, signature, signature_len, curve, md, pkey, in,
David Benjamina2d81f12016-07-08 15:42:16 -0700709 in_len);
Steven Valdez2b8415e2016-06-30 13:27:23 -0400710 }
711
David Benjamin0e950152016-08-13 21:08:56 -0400712 if (is_rsa_pss(&md, signature_algorithm)) {
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400713 return ssl_verify_rsa_pss(ssl, signature, signature_len, md, pkey, in,
714 in_len);
715 }
716
David Benjamina2d81f12016-07-08 15:42:16 -0700717 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
718 return 0;
Steven Valdez2b8415e2016-06-30 13:27:23 -0400719}
720
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700721enum ssl_private_key_result_t ssl_private_key_decrypt(
722 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
723 const uint8_t *in, size_t in_len) {
724 if (ssl->cert->key_method != NULL) {
725 return ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in,
726 in_len);
727 }
728
David Benjamin758d1272015-11-20 17:47:25 -0500729 RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey);
730 if (rsa == NULL) {
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700731 /* Decrypt operations are only supported for RSA keys. */
732 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
733 return ssl_private_key_failure;
734 }
735
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700736 /* Decrypt with no padding. PKCS#1 padding will be removed as part
737 * of the timing-sensitive code by the caller. */
David Benjamin758d1272015-11-20 17:47:25 -0500738 if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
739 return ssl_private_key_failure;
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700740 }
David Benjamin758d1272015-11-20 17:47:25 -0500741 return ssl_private_key_success;
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700742}
743
David Benjamind3440b42016-07-14 14:52:41 -0400744enum ssl_private_key_result_t ssl_private_key_complete(SSL *ssl, uint8_t *out,
745 size_t *out_len,
746 size_t max_out) {
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700747 /* Only custom keys may be asynchronous. */
David Benjamind3440b42016-07-14 14:52:41 -0400748 return ssl->cert->key_method->complete(ssl, out, out_len, max_out);
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700749}
David Benjamin1fb125c2016-07-08 18:52:12 -0700750
751int ssl_private_key_supports_signature_algorithm(SSL *ssl,
752 uint16_t signature_algorithm) {
753 const EVP_MD *md;
Steven Valdez54ed58e2016-08-18 14:03:49 -0400754 if (is_rsa_pkcs1(&md, signature_algorithm) &&
755 ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
David Benjamin0c0b7e12016-07-14 13:47:55 -0400756 return ssl_private_key_type(ssl) == NID_rsaEncryption;
David Benjamin1fb125c2016-07-08 18:52:12 -0700757 }
758
759 int curve;
760 if (is_ecdsa(&curve, &md, signature_algorithm)) {
David Benjamin0c0b7e12016-07-14 13:47:55 -0400761 int type = ssl_private_key_type(ssl);
762 if (!ssl_is_ecdsa_key_type(type)) {
David Benjamin1fb125c2016-07-08 18:52:12 -0700763 return 0;
764 }
765
David Benjamin0c0b7e12016-07-14 13:47:55 -0400766 /* Prior to TLS 1.3, ECDSA curves did not match the signature algorithm. */
767 if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
768 return 1;
David Benjamin1fb125c2016-07-08 18:52:12 -0700769 }
David Benjamin0c0b7e12016-07-14 13:47:55 -0400770
David Benjamin04fe9012016-09-23 14:49:42 -0400771 return curve != NID_undef && type == curve;
David Benjamin1fb125c2016-07-08 18:52:12 -0700772 }
773
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400774 if (is_rsa_pss(&md, signature_algorithm)) {
David Benjamin0e950152016-08-13 21:08:56 -0400775 if (ssl_private_key_type(ssl) != NID_rsaEncryption) {
David Benjamin7944a9f2016-07-12 22:27:01 -0400776 return 0;
777 }
778
779 /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
780 * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
781 * hash in TLS. Reasonable RSA key sizes are large enough for the largest
782 * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for
783 * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check
784 * the size to fall back to another algorithm. */
785 if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) {
786 return 0;
787 }
788
David Benjamind3440b42016-07-14 14:52:41 -0400789 /* RSA-PSS is only supported by message-based private keys. */
790 if (ssl->cert->key_method != NULL && ssl->cert->key_method->sign == NULL) {
791 return 0;
792 }
793
David Benjamin7944a9f2016-07-12 22:27:01 -0400794 return 1;
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400795 }
796
David Benjamin1fb125c2016-07-08 18:52:12 -0700797 return 0;
798}