From 1e4884f615b20946411a74e41eb9c6aa65e2d5f3 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Thu, 24 Sep 2015 10:57:52 -0700 Subject: external/boringssl: sync with upstream. This change imports the current version of BoringSSL. The only local change now is that |BORINGSSL_201509| is defined in base.h. This allows this change to be made without (hopefully) breaking the build. This change will need https://android-review.googlesource.com/172744 to be landed afterwards to update a test. Change-Id: I6d1f463f7785a2423bd846305af91c973c326104 --- src/ssl/ssl_rsa.c | 470 ++++++++++++------------------------------------------ 1 file changed, 101 insertions(+), 369 deletions(-) (limited to 'src/ssl/ssl_rsa.c') diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c index 87f4c1c..ccd3858 100644 --- a/src/ssl/ssl_rsa.c +++ b/src/ssl/ssl_rsa.c @@ -54,79 +54,38 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include +#include -#include #include #include #include -#include -#include #include #include "internal.h" + static int ssl_set_cert(CERT *c, X509 *x509); static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); +static int is_key_type_supported(int key_type) { + return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC; +} + int SSL_use_certificate(SSL *ssl, X509 *x) { if (x == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_certificate, ERR_R_PASSED_NULL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } return ssl_set_cert(ssl->cert, x); } -int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { - int reason_code; - BIO *in; - int ret = 0; - X509 *x = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_SYS_LIB); - goto end; - } - - if (type == SSL_FILETYPE_ASN1) { - reason_code = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - reason_code = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, - ssl->ctx->default_passwd_callback_userdata); - } else { - OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (x == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, reason_code); - goto end; - } - - ret = SSL_use_certificate(ssl, x); - -end: - X509_free(x); - BIO_free(in); - - return ret; -} - int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) { X509 *x; int ret; x = d2i_X509(NULL, &d, (long)len); if (x == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_ASN1, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } @@ -140,13 +99,13 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { int ret; if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_PASSED_NULL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } pkey = EVP_PKEY_new(); if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_EVP_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); return 0; } @@ -160,86 +119,36 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { } static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { - int i; - - i = ssl_cert_type(pkey); - if (i < 0) { - OPENSSL_PUT_ERROR(SSL, ssl_set_pkey, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + if (!is_key_type_supported(pkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } - if (c->pkeys[i].x509 != NULL) { + if (c->x509 != NULL) { /* Sanity-check that the private key and the certificate match, unless the * key is opaque (in case of, say, a smartcard). */ if (!EVP_PKEY_is_opaque(pkey) && - !X509_check_private_key(c->pkeys[i].x509, pkey)) { - X509_free(c->pkeys[i].x509); - c->pkeys[i].x509 = NULL; + !X509_check_private_key(c->x509, pkey)) { + X509_free(c->x509); + c->x509 = NULL; return 0; } } - EVP_PKEY_free(c->pkeys[i].privatekey); - c->pkeys[i].privatekey = EVP_PKEY_up_ref(pkey); - c->key = &(c->pkeys[i]); + EVP_PKEY_free(c->privatekey); + c->privatekey = EVP_PKEY_up_ref(pkey); return 1; } -int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { - int reason_code, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_SYS_LIB); - goto end; - } - - if (type == SSL_FILETYPE_ASN1) { - reason_code = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - reason_code = ERR_R_PEM_LIB; - rsa = - PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, - ssl->ctx->default_passwd_callback_userdata); - } else { - OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, reason_code); - goto end; - } - ret = SSL_use_RSAPrivateKey(ssl, rsa); - RSA_free(rsa); - -end: - BIO_free(in); - return ret; -} - -int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len) { - int ret; - const uint8_t *p; - RSA *rsa; - - p = d; - rsa = d2i_RSAPrivateKey(NULL, &p, (long)len); +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + RSA *rsa = RSA_private_key_from_bytes(der, der_len); if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } - ret = SSL_use_RSAPrivateKey(ssl, rsa); + int ret = SSL_use_RSAPrivateKey(ssl, rsa); RSA_free(rsa); return ret; } @@ -248,7 +157,7 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { int ret; if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -256,46 +165,6 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { return ret; } -int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) { - int reason_code, ret = 0; - BIO *in; - EVP_PKEY *pkey = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_SYS_LIB); - goto end; - } - - if (type == SSL_FILETYPE_PEM) { - reason_code = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback, - ssl->ctx->default_passwd_callback_userdata); - } else if (type == SSL_FILETYPE_ASN1) { - reason_code = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); - } else { - OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, reason_code); - goto end; - } - ret = SSL_use_PrivateKey(ssl, pkey); - EVP_PKEY_free(pkey); - -end: - BIO_free(in); - return ret; -} - int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) { int ret; const uint8_t *p; @@ -304,7 +173,7 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) { p = d; pkey = d2i_PrivateKey(type, NULL, &p, (long)len); if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_ASN1, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } @@ -315,8 +184,7 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) { int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { if (x == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate, - ERR_R_PASSED_NULL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -324,32 +192,28 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { } static int ssl_set_cert(CERT *c, X509 *x) { - EVP_PKEY *pkey; - int i; - - pkey = X509_get_pubkey(x); + EVP_PKEY *pkey = X509_get_pubkey(x); if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_X509_LIB); + OPENSSL_PUT_ERROR(SSL, SSL_R_X509_LIB); return 0; } - i = ssl_cert_type(pkey); - if (i < 0) { - OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + if (!is_key_type_supported(pkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); EVP_PKEY_free(pkey); return 0; } - if (c->pkeys[i].privatekey != NULL) { + if (c->privatekey != NULL) { /* Sanity-check that the private key and the certificate match, unless the * key is opaque (in case of, say, a smartcard). */ - if (!EVP_PKEY_is_opaque(c->pkeys[i].privatekey) && - !X509_check_private_key(x, c->pkeys[i].privatekey)) { + if (!EVP_PKEY_is_opaque(c->privatekey) && + !X509_check_private_key(x, c->privatekey)) { /* don't fail for a cert/key mismatch, just free current private key * (when switching to a different cert & key, first this function should * be used, then ssl_set_pkey */ - EVP_PKEY_free(c->pkeys[i].privatekey); - c->pkeys[i].privatekey = NULL; + EVP_PKEY_free(c->privatekey); + c->privatekey = NULL; /* clear error queue */ ERR_clear_error(); } @@ -357,63 +221,19 @@ static int ssl_set_cert(CERT *c, X509 *x) { EVP_PKEY_free(pkey); - X509_free(c->pkeys[i].x509); - c->pkeys[i].x509 = X509_up_ref(x); - c->key = &(c->pkeys[i]); + X509_free(c->x509); + c->x509 = X509_up_ref(x); return 1; } -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { - int reason_code; - BIO *in; - int ret = 0; - X509 *x = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_SYS_LIB); - goto end; - } - - if (type == SSL_FILETYPE_ASN1) { - reason_code = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - reason_code = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, - SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (x == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, reason_code); - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); - -end: - X509_free(x); - BIO_free(in); - return ret; -} - int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const uint8_t *d) { X509 *x; int ret; x = d2i_X509(NULL, &d, (long)len); if (x == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_ASN1, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } @@ -427,14 +247,13 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { EVP_PKEY *pkey; if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, - ERR_R_PASSED_NULL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } pkey = EVP_PKEY_new(); if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_EVP_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); return 0; } @@ -446,113 +265,28 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { return ret; } -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { - int reason_code, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_SYS_LIB); - goto end; - } - - if (type == SSL_FILETYPE_ASN1) { - reason_code = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - reason_code = ERR_R_PEM_LIB; - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, - SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, reason_code); - goto end; - } - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); - -end: - BIO_free(in); - return ret; -} - -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *d, long len) { - int ret; - const uint8_t *p; - RSA *rsa; - - p = d; - rsa = d2i_RSAPrivateKey(NULL, &p, (long)len); +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + RSA *rsa = RSA_private_key_from_bytes(der, der_len); if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); RSA_free(rsa); return ret; } int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } return ssl_set_pkey(ctx->cert, pkey); } -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { - int reason_code, ret = 0; - BIO *in; - EVP_PKEY *pkey = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_SYS_LIB); - goto end; - } - - if (type == SSL_FILETYPE_PEM) { - reason_code = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else if (type == SSL_FILETYPE_ASN1) { - reason_code = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); - } else { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, reason_code); - goto end; - } - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - -end: - BIO_free(in); - return ret; -} - int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d, long len) { int ret; @@ -562,7 +296,7 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d, p = d; pkey = d2i_PrivateKey(type, NULL, &p, (long)len); if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_ASN1, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } @@ -571,76 +305,74 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d, return ret; } +void SSL_set_private_key_method(SSL *ssl, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ssl->cert->key_method = key_method; +} -/* Read a file that contains our certificate in "PEM" format, possibly followed - * by a sequence of CA certificates that should be sent to the peer in the - * Certificate message. */ -int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) { - BIO *in; - int ret = 0; - X509 *x = NULL; - - ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ +int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids, + size_t num_digests) { + OPENSSL_free(ssl->cert->digest_nids); - in = BIO_new(BIO_s_file()); - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_BUF_LIB); - goto end; + ssl->cert->num_digest_nids = 0; + ssl->cert->digest_nids = BUF_memdup(digest_nids, num_digests*sizeof(int)); + if (ssl->cert->digest_nids == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; } - if (BIO_read_filename(in, file) <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_SYS_LIB); - goto end; - } + ssl->cert->num_digest_nids = num_digests; + return 1; +} - x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - if (x == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_PEM_LIB); - goto end; +int ssl_has_private_key(SSL *ssl) { + return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL; +} + +int ssl_private_key_type(SSL *ssl) { + if (ssl->cert->key_method != NULL) { + return ssl->cert->key_method->type(ssl); } + return EVP_PKEY_id(ssl->cert->privatekey); +} - ret = SSL_CTX_use_certificate(ctx, x); +size_t ssl_private_key_max_signature_len(SSL *ssl) { + if (ssl->cert->key_method != NULL) { + return ssl->cert->key_method->max_signature_len(ssl); + } + return EVP_PKEY_size(ssl->cert->privatekey); +} - if (ERR_peek_error() != 0) { - ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ +enum ssl_private_key_result_t ssl_private_key_sign( + SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md, + const uint8_t *in, size_t in_len) { + if (ssl->cert->key_method != NULL) { + return ssl->cert->key_method->sign(ssl, out, out_len, max_out, md, in, + in_len); } - if (ret) { - /* If we could set up our certificate, now proceed to the CA - * certificates. */ - X509 *ca; - int r; - uint32_t err; - - SSL_CTX_clear_chain_certs(ctx); - - while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata)) != - NULL) { - r = SSL_CTX_add0_chain_cert(ctx, ca); - if (!r) { - X509_free(ca); - ret = 0; - goto end; - } - /* Note that we must not free r if it was successfully added to the chain - * (while we must free the main certificate, since its reference count is - * increased by SSL_CTX_use_certificate). */ - } + enum ssl_private_key_result_t ret = ssl_private_key_failure; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(ssl->cert->privatekey, NULL); + if (ctx == NULL) { + goto end; + } - /* When the while loop ends, it's usually just EOF. */ - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_PEM && - ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { - ERR_clear_error(); - } else { - ret = 0; /* some real error */ - } + size_t len = max_out; + if (!EVP_PKEY_sign_init(ctx) || + !EVP_PKEY_CTX_set_signature_md(ctx, md) || + !EVP_PKEY_sign(ctx, out, &len, in, in_len)) { + goto end; } + *out_len = len; + ret = ssl_private_key_success; end: - X509_free(x); - BIO_free(in); + EVP_PKEY_CTX_free(ctx); return ret; } + +enum ssl_private_key_result_t ssl_private_key_sign_complete( + SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) { + /* Only custom keys may be asynchronous. */ + return ssl->cert->key_method->sign_complete(ssl, out, out_len, max_out); +} -- cgit v1.1