1 /* 2 * Copyright (c) 2021 Yubico AB. All rights reserved. 3 * Use of this source code is governed by a BSD-style 4 * license that can be found in the LICENSE file. 5 */ 6 7 #include <openssl/rsa.h> 8 #include <openssl/obj_mac.h> 9 10 #include "fido.h" 11 12 #if defined(LIBRESSL_VERSION_NUMBER) 13 static EVP_MD * 14 rs1_get_EVP_MD(void) 15 { 16 const EVP_MD *from; 17 EVP_MD *to = NULL; 18 19 if ((from = EVP_sha1()) != NULL && (to = malloc(sizeof(*to))) != NULL) 20 memcpy(to, from, sizeof(*to)); 21 22 return (to); 23 } 24 25 static void 26 rs1_free_EVP_MD(EVP_MD *md) 27 { 28 freezero(md, sizeof(*md)); 29 } 30 #elif OPENSSL_VERSION_NUMBER >= 0x30000000 31 static EVP_MD * 32 rs1_get_EVP_MD(void) 33 { 34 return (EVP_MD_fetch(NULL, "SHA-1", NULL)); 35 } 36 37 static void 38 rs1_free_EVP_MD(EVP_MD *md) 39 { 40 EVP_MD_free(md); 41 } 42 #else 43 static EVP_MD * 44 rs1_get_EVP_MD(void) 45 { 46 const EVP_MD *md; 47 48 if ((md = EVP_sha1()) == NULL) 49 return (NULL); 50 51 return (EVP_MD_meth_dup(md)); 52 } 53 54 static void 55 rs1_free_EVP_MD(EVP_MD *md) 56 { 57 EVP_MD_meth_free(md); 58 } 59 #endif /* LIBRESSL_VERSION_NUMBER */ 60 61 int 62 rs1_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, 63 const fido_blob_t *sig) 64 { 65 EVP_PKEY_CTX *pctx = NULL; 66 EVP_MD *md = NULL; 67 int ok = -1; 68 69 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { 70 fido_log_debug("%s: EVP_PKEY_base_id", __func__); 71 goto fail; 72 } 73 74 if ((md = rs1_get_EVP_MD()) == NULL) { 75 fido_log_debug("%s: rs1_get_EVP_MD", __func__); 76 goto fail; 77 } 78 79 if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || 80 EVP_PKEY_verify_init(pctx) != 1 || 81 EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) != 1 || 82 EVP_PKEY_CTX_set_signature_md(pctx, md) != 1) { 83 fido_log_debug("%s: EVP_PKEY_CTX", __func__); 84 goto fail; 85 } 86 87 if (EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr, 88 dgst->len) != 1) { 89 fido_log_debug("%s: EVP_PKEY_verify", __func__); 90 goto fail; 91 } 92 93 ok = 0; 94 fail: 95 EVP_PKEY_CTX_free(pctx); 96 rs1_free_EVP_MD(md); 97 98 return (ok); 99 } 100