Apply upstream patches for OpenSSL 3.0

This commit is contained in:
Gary Buhrmaster 2021-09-15 15:29:05 +00:00
parent 70bb7270bb
commit e278c950a3
9 changed files with 971 additions and 1 deletions

View File

@ -0,0 +1,204 @@
From c7c07de1dbfb0a33fb096f7fa2fd901e7485d6eb Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Wed, 28 Jul 2021 10:23:28 +0200
Subject: [PATCH 06/70] Replace SHA256_* with EVP_* equivalents
SHA256_{Init,Update,Final} are marked as deprecated in OpenSSL 3.0.
Given that alternatives exist in OpenSSL 1.1 and LibreSSL, switch to
them as a first step towards OpenSSL 3.0 integration.
Joint work with Dmitry Belyavskiy.
---
fuzz/wrap.c | 48 ++++++++++++++++++++++++------------------------
fuzz/wrapped.sym | 6 +++---
src/assert.c | 16 +++++++++++-----
src/cred.c | 39 ++++++++++++++++++++++++---------------
4 files changed, 62 insertions(+), 47 deletions(-)
diff --git a/fuzz/wrap.c b/fuzz/wrap.c
index 5b91a64..188dbd4 100644
--- a/fuzz/wrap.c
+++ b/fuzz/wrap.c
@@ -136,30 +136,6 @@ WRAP(int,
1
)
-WRAP(int,
- SHA256_Init,
- (SHA256_CTX *c),
- 0,
- (c),
- 1
-)
-
-WRAP(int,
- SHA256_Update,
- (SHA256_CTX *c, const void *data, size_t len),
- 0,
- (c, data, len),
- 1
-)
-
-WRAP(int,
- SHA256_Final,
- (unsigned char *md, SHA256_CTX *c),
- 0,
- (md, c),
- 1
-)
-
WRAP(RSA *,
EVP_PKEY_get0_RSA,
(EVP_PKEY *pkey),
@@ -201,6 +177,30 @@ WRAP(int,
1
)
+WRAP(int,
+ EVP_DigestInit_ex,
+ (EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl),
+ 0,
+ (ctx, type, impl),
+ 1
+)
+
+WRAP(int,
+ EVP_DigestUpdate,
+ (EVP_MD_CTX *ctx, const void *data, size_t count),
+ 0,
+ (ctx, data, count),
+ 1
+)
+
+WRAP(int,
+ EVP_DigestFinal_ex,
+ (EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize),
+ 0,
+ (ctx, md, isize),
+ 1
+)
+
WRAP(BIGNUM *,
BN_bin2bn,
(const unsigned char *s, int len, BIGNUM *ret),
diff --git a/fuzz/wrapped.sym b/fuzz/wrapped.sym
index de4f24a..87d4f28 100644
--- a/fuzz/wrapped.sym
+++ b/fuzz/wrapped.sym
@@ -31,6 +31,9 @@ EVP_CIPHER_CTX_set_padding
EVP_CipherInit
EVP_DecryptInit_ex
EVP_DecryptUpdate
+EVP_DigestFinal_ex
+EVP_DigestInit_ex
+EVP_DigestUpdate
EVP_DigestVerifyInit
EVP_EncryptInit_ex
EVP_EncryptUpdate
@@ -61,9 +64,6 @@ ioctl
malloc
RSA_set0_key
SHA256
-SHA256_Final
-SHA256_Init
-SHA256_Update
strdup
udev_device_get_devnode
udev_device_get_parent_with_subsystem_devtype
diff --git a/src/assert.c b/src/assert.c
index b36f8e3..d28484c 100644
--- a/src/assert.c
+++ b/src/assert.c
@@ -372,7 +372,8 @@ fido_get_signed_hash(int cose_alg, fido_blob_t *dgst,
unsigned char *authdata_ptr = NULL;
size_t authdata_len;
struct cbor_load_result cbor;
- SHA256_CTX ctx;
+ const EVP_MD *md = NULL;
+ EVP_MD_CTX *ctx = NULL;
int ok = -1;
if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len,
@@ -386,10 +387,13 @@ fido_get_signed_hash(int cose_alg, fido_blob_t *dgst,
authdata_len = cbor_bytestring_length(item);
if (cose_alg != COSE_EDDSA) {
- if (dgst->len < SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 ||
- SHA256_Update(&ctx, authdata_ptr, authdata_len) == 0 ||
- SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 ||
- SHA256_Final(dgst->ptr, &ctx) == 0) {
+ if (dgst->len < SHA256_DIGEST_LENGTH ||
+ (md = EVP_sha256()) == NULL ||
+ (ctx = EVP_MD_CTX_new()) == NULL ||
+ EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+ EVP_DigestUpdate(ctx, authdata_ptr, authdata_len) != 1 ||
+ EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+ EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) {
fido_log_debug("%s: sha256", __func__);
goto fail;
}
@@ -411,6 +415,8 @@ fail:
if (item != NULL)
cbor_decref(&item);
+ EVP_MD_CTX_free(ctx);
+
return (ok);
}
diff --git a/src/cred.c b/src/cred.c
index 5e65b08..e38972b 100644
--- a/src/cred.c
+++ b/src/cred.c
@@ -225,24 +225,33 @@ get_signed_hash_u2f(fido_blob_t *dgst, const unsigned char *rp_id,
size_t rp_id_len, const fido_blob_t *clientdata, const fido_blob_t *id,
const es256_pk_t *pk)
{
- const uint8_t zero = 0;
- const uint8_t four = 4; /* uncompressed point */
- SHA256_CTX ctx;
-
- if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 ||
- SHA256_Update(&ctx, &zero, sizeof(zero)) == 0 ||
- SHA256_Update(&ctx, rp_id, rp_id_len) == 0 ||
- SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 ||
- SHA256_Update(&ctx, id->ptr, id->len) == 0 ||
- SHA256_Update(&ctx, &four, sizeof(four)) == 0 ||
- SHA256_Update(&ctx, pk->x, sizeof(pk->x)) == 0 ||
- SHA256_Update(&ctx, pk->y, sizeof(pk->y)) == 0 ||
- SHA256_Final(dgst->ptr, &ctx) == 0) {
+ const uint8_t zero = 0;
+ const uint8_t four = 4; /* uncompressed point */
+ const EVP_MD *md = NULL;
+ EVP_MD_CTX *ctx = NULL;
+ int ok = -1;
+
+ if (dgst->len != SHA256_DIGEST_LENGTH ||
+ (md = EVP_sha256()) == NULL ||
+ (ctx = EVP_MD_CTX_new()) == NULL ||
+ EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+ EVP_DigestUpdate(ctx, &zero, sizeof(zero)) != 1 ||
+ EVP_DigestUpdate(ctx, rp_id, rp_id_len) != 1 ||
+ EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+ EVP_DigestUpdate(ctx, id->ptr, id->len) != 1 ||
+ EVP_DigestUpdate(ctx, &four, sizeof(four)) != 1 ||
+ EVP_DigestUpdate(ctx, pk->x, sizeof(pk->x)) != 1 ||
+ EVP_DigestUpdate(ctx, pk->y, sizeof(pk->y)) != 1 ||
+ EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) {
fido_log_debug("%s: sha256", __func__);
- return (-1);
+ goto fail;
}
- return (0);
+ ok = 0;
+fail:
+ EVP_MD_CTX_free(ctx);
+
+ return (ok);
}
static int
--
2.31.1

View File

@ -0,0 +1,363 @@
From e4f0b9aee150be7291ac57bc7c27f335f5c75694 Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Mon, 2 Aug 2021 19:04:43 +0200
Subject: [PATCH 14/70] Rename and move fido_verify_sig_{eddsa,es256,rs256}
Rename fido_verify_sig_{eddsa,es256,rs256} and move them to
{eddsa,es256,rs256}.c respectively. No functional change.
---
src/assert.c | 124 ++-------------------------------------------------
src/cred.c | 6 +--
src/eddsa.c | 47 +++++++++++++++++++
src/es256.c | 36 +++++++++++++++
src/extern.h | 6 +--
src/rs256.c | 35 +++++++++++++++
6 files changed, 127 insertions(+), 127 deletions(-)
diff --git a/src/assert.c b/src/assert.c
index d28484c..a3efbf5 100644
--- a/src/assert.c
+++ b/src/assert.c
@@ -4,7 +4,6 @@
* license that can be found in the LICENSE file.
*/
-#include <openssl/ecdsa.h>
#include <openssl/sha.h>
#include "fido.h"
@@ -420,123 +419,6 @@ fail:
return (ok);
}
-int
-fido_verify_sig_es256(const fido_blob_t *dgst, const es256_pk_t *pk,
- const fido_blob_t *sig)
-{
- EVP_PKEY *pkey = NULL;
- EC_KEY *ec = NULL;
- int ok = -1;
-
- /* ECDSA_verify needs ints */
- if (dgst->len > INT_MAX || sig->len > INT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
- }
-
- if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL ||
- (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) {
- fido_log_debug("%s: pk -> ec", __func__);
- goto fail;
- }
-
- if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
- (int)sig->len, ec) != 1) {
- fido_log_debug("%s: ECDSA_verify", __func__);
- goto fail;
- }
-
- ok = 0;
-fail:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
-
- return (ok);
-}
-
-int
-fido_verify_sig_rs256(const fido_blob_t *dgst, const rs256_pk_t *pk,
- const fido_blob_t *sig)
-{
- EVP_PKEY *pkey = NULL;
- RSA *rsa = NULL;
- int ok = -1;
-
- /* RSA_verify needs unsigned ints */
- if (dgst->len > UINT_MAX || sig->len > UINT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
- }
-
- if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL ||
- (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) {
- fido_log_debug("%s: pk -> ec", __func__);
- goto fail;
- }
-
- if (RSA_verify(NID_sha256, dgst->ptr, (unsigned int)dgst->len, sig->ptr,
- (unsigned int)sig->len, rsa) != 1) {
- fido_log_debug("%s: RSA_verify", __func__);
- goto fail;
- }
-
- ok = 0;
-fail:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
-
- return (ok);
-}
-
-int
-fido_verify_sig_eddsa(const fido_blob_t *dgst, const eddsa_pk_t *pk,
- const fido_blob_t *sig)
-{
- EVP_PKEY *pkey = NULL;
- EVP_MD_CTX *mdctx = NULL;
- int ok = -1;
-
- /* EVP_DigestVerify needs ints */
- if (dgst->len > INT_MAX || sig->len > INT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
- }
-
- if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) {
- fido_log_debug("%s: pk -> pkey", __func__);
- goto fail;
- }
-
- if ((mdctx = EVP_MD_CTX_new()) == NULL) {
- fido_log_debug("%s: EVP_MD_CTX_new", __func__);
- goto fail;
- }
-
- if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) {
- fido_log_debug("%s: EVP_DigestVerifyInit", __func__);
- goto fail;
- }
-
- if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr,
- dgst->len) != 1) {
- fido_log_debug("%s: EVP_DigestVerify", __func__);
- goto fail;
- }
-
- ok = 0;
-fail:
- if (mdctx != NULL)
- EVP_MD_CTX_free(mdctx);
-
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
-
- return (ok);
-}
-
int
fido_assert_verify(const fido_assert_t *assert, size_t idx, int cose_alg,
const void *pk)
@@ -595,13 +477,13 @@ fido_assert_verify(const fido_assert_t *assert, size_t idx, int cose_alg,
switch (cose_alg) {
case COSE_ES256:
- ok = fido_verify_sig_es256(&dgst, pk, &stmt->sig);
+ ok = es256_verify_sig(&dgst, pk, &stmt->sig);
break;
case COSE_RS256:
- ok = fido_verify_sig_rs256(&dgst, pk, &stmt->sig);
+ ok = rs256_verify_sig(&dgst, pk, &stmt->sig);
break;
case COSE_EDDSA:
- ok = fido_verify_sig_eddsa(&dgst, pk, &stmt->sig);
+ ok = eddsa_verify_sig(&dgst, pk, &stmt->sig);
break;
default:
fido_log_debug("%s: unsupported cose_alg %d", __func__,
diff --git a/src/cred.c b/src/cred.c
index ce5be34..bce5c13 100644
--- a/src/cred.c
+++ b/src/cred.c
@@ -444,15 +444,15 @@ fido_cred_verify_self(const fido_cred_t *cred)
switch (cred->attcred.type) {
case COSE_ES256:
- ok = fido_verify_sig_es256(&dgst, &cred->attcred.pubkey.es256,
+ ok = es256_verify_sig(&dgst, &cred->attcred.pubkey.es256,
&cred->attstmt.sig);
break;
case COSE_RS256:
- ok = fido_verify_sig_rs256(&dgst, &cred->attcred.pubkey.rs256,
+ ok = rs256_verify_sig(&dgst, &cred->attcred.pubkey.rs256,
&cred->attstmt.sig);
break;
case COSE_EDDSA:
- ok = fido_verify_sig_eddsa(&dgst, &cred->attcred.pubkey.eddsa,
+ ok = eddsa_verify_sig(&dgst, &cred->attcred.pubkey.eddsa,
&cred->attstmt.sig);
break;
default:
diff --git a/src/eddsa.c b/src/eddsa.c
index 89b84c5..dffbdf7 100644
--- a/src/eddsa.c
+++ b/src/eddsa.c
@@ -170,3 +170,50 @@ eddsa_pk_from_EVP_PKEY(eddsa_pk_t *pk, const EVP_PKEY *pkey)
return (FIDO_OK);
}
+
+int
+eddsa_verify_sig(const fido_blob_t *dgst, const eddsa_pk_t *pk,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY *pkey = NULL;
+ EVP_MD_CTX *mdctx = NULL;
+ int ok = -1;
+
+ /* EVP_DigestVerify needs ints */
+ if (dgst->len > INT_MAX || sig->len > INT_MAX) {
+ fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
+ dgst->len, sig->len);
+ return (-1);
+ }
+
+ if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) {
+ fido_log_debug("%s: pk -> pkey", __func__);
+ goto fail;
+ }
+
+ if ((mdctx = EVP_MD_CTX_new()) == NULL) {
+ fido_log_debug("%s: EVP_MD_CTX_new", __func__);
+ goto fail;
+ }
+
+ if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) {
+ fido_log_debug("%s: EVP_DigestVerifyInit", __func__);
+ goto fail;
+ }
+
+ if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_DigestVerify", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ if (mdctx != NULL)
+ EVP_MD_CTX_free(mdctx);
+
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+
+ return (ok);
+}
diff --git a/src/es256.c b/src/es256.c
index 9cdb48e..dcdcb80 100644
--- a/src/es256.c
+++ b/src/es256.c
@@ -5,6 +5,7 @@
*/
#include <openssl/bn.h>
+#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include "fido.h"
@@ -451,3 +452,38 @@ fail:
return (ok);
}
+
+int
+es256_verify_sig(const fido_blob_t *dgst, const es256_pk_t *pk,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY *pkey = NULL;
+ EC_KEY *ec = NULL;
+ int ok = -1;
+
+ /* ECDSA_verify needs ints */
+ if (dgst->len > INT_MAX || sig->len > INT_MAX) {
+ fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
+ dgst->len, sig->len);
+ return (-1);
+ }
+
+ if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL ||
+ (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) {
+ fido_log_debug("%s: pk -> ec", __func__);
+ goto fail;
+ }
+
+ if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
+ (int)sig->len, ec) != 1) {
+ fido_log_debug("%s: ECDSA_verify", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+
+ return (ok);
+}
diff --git a/src/extern.h b/src/extern.h
index 91e129b..a2d1ba4 100644
--- a/src/extern.h
+++ b/src/extern.h
@@ -200,11 +200,11 @@ int fido_get_random(void *, size_t);
int fido_sha256(fido_blob_t *, const u_char *, size_t);
/* crypto */
-int fido_verify_sig_es256(const fido_blob_t *, const es256_pk_t *,
+int es256_verify_sig(const fido_blob_t *, const es256_pk_t *,
const fido_blob_t *);
-int fido_verify_sig_rs256(const fido_blob_t *, const rs256_pk_t *,
+int rs256_verify_sig(const fido_blob_t *, const rs256_pk_t *,
const fido_blob_t *);
-int fido_verify_sig_eddsa(const fido_blob_t *, const eddsa_pk_t *,
+int eddsa_verify_sig(const fido_blob_t *, const eddsa_pk_t *,
const fido_blob_t *);
int fido_get_signed_hash(int, fido_blob_t *, const fido_blob_t *,
const fido_blob_t *);
diff --git a/src/rs256.c b/src/rs256.c
index c6d87a3..001417b 100644
--- a/src/rs256.c
+++ b/src/rs256.c
@@ -198,3 +198,38 @@ rs256_pk_from_RSA(rs256_pk_t *pk, const RSA *rsa)
return (FIDO_OK);
}
+
+int
+rs256_verify_sig(const fido_blob_t *dgst, const rs256_pk_t *pk,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY *pkey = NULL;
+ RSA *rsa = NULL;
+ int ok = -1;
+
+ /* RSA_verify needs unsigned ints */
+ if (dgst->len > UINT_MAX || sig->len > UINT_MAX) {
+ fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
+ dgst->len, sig->len);
+ return (-1);
+ }
+
+ if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL ||
+ (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) {
+ fido_log_debug("%s: pk -> ec", __func__);
+ goto fail;
+ }
+
+ if (RSA_verify(NID_sha256, dgst->ptr, (unsigned int)dgst->len, sig->ptr,
+ (unsigned int)sig->len, rsa) != 1) {
+ fido_log_debug("%s: RSA_verify", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+
+ return (ok);
+}
--
2.31.1

View File

@ -0,0 +1,85 @@
From 2d258bc64a67bb66990538e00e11e094b49cd942 Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Tue, 3 Aug 2021 08:48:43 +0200
Subject: [PATCH 15/70] cred: rework verify_sig
Rework verify_sig (used by fido_cred_verify) to accept key types
other than ES256, while making the code OpenSSL 3.0 compatible.
Diff from Dmitry Belyavskiy (@beldmit).
---
man/fido_cred_verify.3 | 1 -
src/cred.c | 26 ++++++++++++--------------
2 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/man/fido_cred_verify.3 b/man/fido_cred_verify.3
index d90a4c7..e5179d9 100644
--- a/man/fido_cred_verify.3
+++ b/man/fido_cred_verify.3
@@ -47,7 +47,6 @@ The attestation type implemented by
.Fn fido_cred_verify
is
.Em Basic Attestation .
-The attestation key pair is assumed to be of the type ES256.
Other attestation formats and types are not supported.
.Sh RETURN VALUES
The error codes returned by
diff --git a/src/cred.c b/src/cred.c
index bce5c13..6b99476 100644
--- a/src/cred.c
+++ b/src/cred.c
@@ -261,13 +261,12 @@ verify_sig(const fido_blob_t *dgst, const fido_blob_t *x5c,
BIO *rawcert = NULL;
X509 *cert = NULL;
EVP_PKEY *pkey = NULL;
- EC_KEY *ec;
+ EVP_PKEY_CTX *pctx = NULL;
int ok = -1;
/* openssl needs ints */
- if (dgst->len > INT_MAX || x5c->len > INT_MAX || sig->len > INT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, x5c->len=%zu, sig->len=%zu",
- __func__, dgst->len, x5c->len, sig->len);
+ if (x5c->len > INT_MAX) {
+ fido_log_debug("%s: x5c->len=%zu", __func__, x5c->len);
return (-1);
}
@@ -275,25 +274,24 @@ verify_sig(const fido_blob_t *dgst, const fido_blob_t *x5c,
if ((rawcert = BIO_new_mem_buf(x5c->ptr, (int)x5c->len)) == NULL ||
(cert = d2i_X509_bio(rawcert, NULL)) == NULL ||
(pkey = X509_get_pubkey(cert)) == NULL ||
- (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) {
+ (pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) {
fido_log_debug("%s: x509 key", __func__);
goto fail;
}
- if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
- (int)sig->len, ec) != 1) {
- fido_log_debug("%s: ECDSA_verify", __func__);
+ if (EVP_PKEY_verify_init(pctx) != 1 ||
+ EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_PKEY_verify", __func__);
goto fail;
}
ok = 0;
fail:
- if (rawcert != NULL)
- BIO_free(rawcert);
- if (cert != NULL)
- X509_free(cert);
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
+ BIO_free(rawcert);
+ X509_free(cert);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(pctx);
return (ok);
}
--
2.31.1

View File

@ -0,0 +1,28 @@
From cbf522fc65e16bc206810a6a0de9d757558ff55b Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Tue, 3 Aug 2021 13:28:09 +0200
Subject: [PATCH 16/70] ecdh: explicit cast to silence warning with OpenSSL 3.0
EVP_PKEY_CTX_add1_hkdf_info takes a const unsigned char * in OpenSSL
3, and a void * in OpenSSL 1.1. We pass a char *, so add an explicit
cast to void * to satisfy both variations.
---
src/ecdh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ecdh.c b/src/ecdh.c
index 3ea47ae..1e85e7e 100644
--- a/src/ecdh.c
+++ b/src/ecdh.c
@@ -56,7 +56,7 @@ hkdf_sha256(uint8_t *key, char *info, fido_blob_t *secret)
EVP_PKEY_CTX_set_hkdf_md(ctx, md) < 1 ||
EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, sizeof(salt)) < 1 ||
EVP_PKEY_CTX_set1_hkdf_key(ctx, secret->ptr, (int)secret->len) < 1 ||
- EVP_PKEY_CTX_add1_hkdf_info(ctx, info, (int)strlen(info)) < 1) {
+ EVP_PKEY_CTX_add1_hkdf_info(ctx, (void *)info, (int)strlen(info)) < 1) {
fido_log_debug("%s: EVP_PKEY_CTX", __func__);
goto fail;
}
--
2.31.1

View File

@ -0,0 +1,59 @@
From a2955599e77237d6daf99301ccdf9f1d9c2ae181 Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Tue, 3 Aug 2021 13:51:52 +0200
Subject: [PATCH 17/70] es256: make es256_verify_sig OpenSSL 3.0 compatible
Use the EVP_PKEY_verify family of functions to make es256_verify_sig
compatible with OpenSSL 3.0. Diff from Dmitry Belyavskiy (@beldmit).
---
src/es256.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/src/es256.c b/src/es256.c
index dcdcb80..f2f4024 100644
--- a/src/es256.c
+++ b/src/es256.c
@@ -458,32 +458,26 @@ es256_verify_sig(const fido_blob_t *dgst, const es256_pk_t *pk,
const fido_blob_t *sig)
{
EVP_PKEY *pkey = NULL;
- EC_KEY *ec = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
int ok = -1;
- /* ECDSA_verify needs ints */
- if (dgst->len > INT_MAX || sig->len > INT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
- }
-
if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL ||
- (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) {
+ (pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) {
fido_log_debug("%s: pk -> ec", __func__);
goto fail;
}
- if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
- (int)sig->len, ec) != 1) {
- fido_log_debug("%s: ECDSA_verify", __func__);
+ if (EVP_PKEY_verify_init(pctx) != 1 ||
+ EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_PKEY_verify", __func__);
goto fail;
}
ok = 0;
fail:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(pctx);
return (ok);
}
--
2.31.1

View File

@ -0,0 +1,49 @@
From f769df638f942bc10f1062ac1c5e1ca51b047bf7 Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Tue, 3 Aug 2021 14:47:21 +0200
Subject: [PATCH 18/70] rs256: drop OpenSSL 1.0 compatibility shim
---
src/rs256.c | 26 --------------------------
1 file changed, 26 deletions(-)
diff --git a/src/rs256.c b/src/rs256.c
index 001417b..ac0b1f2 100644
--- a/src/rs256.c
+++ b/src/rs256.c
@@ -11,32 +11,6 @@
#include "fido.h"
#include "fido/rs256.h"
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-static int
-RSA_bits(const RSA *r)
-{
- return (BN_num_bits(r->n));
-}
-
-static int
-RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
-{
- r->n = n;
- r->e = e;
- r->d = d;
-
- return (1);
-}
-
-static void
-RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
-{
- *n = r->n;
- *e = r->e;
- *d = r->d;
-}
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
-
static int
decode_bignum(const cbor_item_t *item, void *ptr, size_t len)
{
--
2.31.1

View File

@ -0,0 +1,135 @@
From 4632562e363249f0b5d92a8863c19e2662e55b19 Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Tue, 3 Aug 2021 14:50:12 +0200
Subject: [PATCH 19/70] rs256: make rs256_verify_sig OpenSSL 3.0 compatible
Use the EVP_PKEY_verify family of functions to make rs256_verify_sig
compatible with OpenSSL 3.0. Diff from Dmitry Belyavskiy (@beldmit).
---
src/rs256.c | 86 +++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 71 insertions(+), 15 deletions(-)
diff --git a/src/rs256.c b/src/rs256.c
index ac0b1f2..881b575 100644
--- a/src/rs256.c
+++ b/src/rs256.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -11,6 +11,55 @@
#include "fido.h"
#include "fido/rs256.h"
+#if defined(LIBRESSL_VERSION_NUMBER)
+static EVP_MD *
+rs256_get_EVP_MD(void)
+{
+ const EVP_MD *from;
+ EVP_MD *to = NULL;
+
+ if ((from = EVP_sha256()) != NULL && (to = malloc(sizeof(*to))) != NULL)
+ memcpy(to, from, sizeof(*to));
+
+ return (to);
+}
+
+static void
+rs256_free_EVP_MD(EVP_MD *md)
+{
+ freezero(md, sizeof(*md));
+}
+#elif OPENSSL_VERSION_NUMBER >= 0x30000000
+static EVP_MD *
+rs256_get_EVP_MD(void)
+{
+ return (EVP_MD_fetch(NULL, "SHA2-256", NULL));
+}
+
+static void
+rs256_free_EVP_MD(EVP_MD *md)
+{
+ EVP_MD_free(md);
+}
+#else
+static EVP_MD *
+rs256_get_EVP_MD(void)
+{
+ const EVP_MD *md;
+
+ if ((md = EVP_sha256()) == NULL)
+ return (NULL);
+
+ return (EVP_MD_meth_dup(md));
+}
+
+static void
+rs256_free_EVP_MD(EVP_MD *md)
+{
+ EVP_MD_meth_free(md);
+}
+#endif /* LIBRESSL_VERSION_NUMBER */
+
static int
decode_bignum(const cbor_item_t *item, void *ptr, size_t len)
{
@@ -178,32 +227,39 @@ rs256_verify_sig(const fido_blob_t *dgst, const rs256_pk_t *pk,
const fido_blob_t *sig)
{
EVP_PKEY *pkey = NULL;
- RSA *rsa = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
+ EVP_MD *md = NULL;
int ok = -1;
- /* RSA_verify needs unsigned ints */
- if (dgst->len > UINT_MAX || sig->len > UINT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
+ if ((md = rs256_get_EVP_MD()) == NULL) {
+ fido_log_debug("%s: rs256_get_EVP_MD", __func__);
+ goto fail;
+ }
+
+ if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL) {
+ fido_log_debug("%s: rs256_pk_to_EVP_PKEY", __func__);
+ goto fail;
}
- if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL ||
- (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) {
- fido_log_debug("%s: pk -> ec", __func__);
+ if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL ||
+ EVP_PKEY_verify_init(pctx) != 1 ||
+ EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) != 1 ||
+ EVP_PKEY_CTX_set_signature_md(pctx, md) != 1) {
+ fido_log_debug("%s: EVP_PKEY_CTX", __func__);
goto fail;
}
- if (RSA_verify(NID_sha256, dgst->ptr, (unsigned int)dgst->len, sig->ptr,
- (unsigned int)sig->len, rsa) != 1) {
- fido_log_debug("%s: RSA_verify", __func__);
+ if (EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_PKEY_verify", __func__);
goto fail;
}
ok = 0;
fail:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(pctx);
+ rs256_free_EVP_MD(md);
return (ok);
}
--
2.31.1

View File

@ -0,0 +1,34 @@
From 29c0eca2a2cc19201d9f231005920c02abfffbca Mon Sep 17 00:00:00 2001
From: pedro martelletto <pedro@yubico.com>
Date: Tue, 3 Aug 2021 16:26:22 +0200
Subject: [PATCH 20/70] Define OPENSSL_API_COMPAT if OpenSSL 3.0 is detected
If OpenSSL 3.0 is detected, build with OPENSSL_API_COMPAT set to
0x10100000L to suppress deprecation warnings on otherwise working
code. Discussed with Dmitry Belyavskiy (@beldmit).
---
CMakeLists.txt | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ecf3448..10bb8a6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -277,9 +277,14 @@ else()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2")
+ if(CRYPTO_VERSION VERSION_GREATER_EQUAL 3.0)
+ add_definitions(-DOPENSSL_API_COMPAT=0x10100000L)
+ endif()
+
if(FUZZ)
add_definitions(-DFIDO_FUZZ)
endif()
+
if(LIBFUZZER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer-no-link")
endif()
--
2.31.1

View File

@ -1,7 +1,7 @@
Name: libfido2
Version: 1.8.0
Release: 2%{?dist}
Release: 3%{?dist}
Summary: FIDO2 library
License: BSD
@ -10,6 +10,16 @@ Source0: https://developers.yubico.com/%{name}/Releases/%{name}-%{version
Source1: https://developers.yubico.com/%{name}/Releases/%{name}-%{version}.tar.gz.sig
Source2: yubico-release-gpgkeys.asc
# Upstream patches for OpenSSL 3.0 compatibility
Patch0001: 0001-Replace-SHA256_-with-EVP_-equivalents.patch
Patch0002: 0002-Rename-and-move-fido_verify_sig_-eddsa-es256-rs256.patch
Patch0003: 0003-cred-rework-verify_sig.patch
Patch0004: 0004-ecdh-explicit-cast-to-silence-warning-with-OpenSSL-3.patch
Patch0005: 0005-es256-make-es256_verify_sig-OpenSSL-3.0-compatible.patch
Patch0006: 0006-rs256-drop-OpenSSL-1.0-compatibility-shim.patch
Patch0007: 0007-rs256-make-rs256_verify_sig-OpenSSL-3.0-compatible.patch
Patch0008: 0008-Define-OPENSSL_API_COMPAT-if-OpenSSL-3.0-is-detected.patch
BuildRequires: cmake
BuildRequires: hidapi-devel
BuildRequires: libcbor-devel
@ -86,6 +96,9 @@ find %{buildroot} -type f -name "*.a" -delete -print
%changelog
* Wed Sep 15 2021 Gary Buhrmaster <gary.buhrmaster@gmail.com> - 1.8.0-3
- Apply upstream patches for OpenSSL 3.0
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 1.8.0-2
- Rebuilt with OpenSSL 3.0.0