static int ssl_verify_rsa_pkcs1(SSL *ssl, const uint8_t *signature, size_t signature_len, const EVP_MD *md, EVP_PKEY *pkey, const uint8_t *in, size_t in_len) { if (pkey->type != EVP_PKEY_RSA) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) && EVP_DigestVerifyUpdate(&md_ctx, in, in_len) && EVP_DigestVerifyFinal(&md_ctx, signature, signature_len); EVP_MD_CTX_cleanup(&md_ctx); return ret; }
static int test_EVP_DigestSignInit(void) { int ret = 0; EVP_PKEY *pkey = NULL; unsigned char *sig = NULL; size_t sig_len = 0; EVP_MD_CTX *md_ctx, *md_ctx_verify = NULL; if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()) || !TEST_ptr(md_ctx_verify = EVP_MD_CTX_new()) || !TEST_ptr(pkey = load_example_rsa_key())) goto out; if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey)) || !TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg)))) goto out; /* Determine the size of the signature. */ if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) || !TEST_size_t_eq(sig_len, (size_t)EVP_PKEY_size(pkey))) goto out; if (!TEST_ptr(sig = OPENSSL_malloc(sig_len)) || !TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len))) goto out; /* Ensure that the signature round-trips. */ if (!TEST_true(EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sha256(), NULL, pkey)) || !TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg))) || !TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len))) goto out; ret = 1; out: EVP_MD_CTX_free(md_ctx); EVP_MD_CTX_free(md_ctx_verify); EVP_PKEY_free(pkey); OPENSSL_free(sig); return ret; }
int SCT_verify(const SCT_CTX *sctx, const SCT *sct) { EVP_MD_CTX *ctx = NULL; int ret = 0; if (!SCT_is_complete(sct) || sctx->pkey == NULL || sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET || (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) { CTerr(CT_F_SCT_VERIFY, CT_R_SCT_NOT_SET); return 0; } if (sct->version != SCT_VERSION_V1) { CTerr(CT_F_SCT_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION); return 0; } if (sct->log_id_len != sctx->pkeyhashlen || memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) { CTerr(CT_F_SCT_VERIFY, CT_R_SCT_LOG_ID_MISMATCH); return 0; } ctx = EVP_MD_CTX_new(); if (ctx == NULL) goto end; if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey)) goto end; if (!sct_ctx_update(ctx, sctx, sct)) goto end; /* Verify signature */ ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len); /* If ret < 0 some other error: fall through without setting error */ if (ret == 0) CTerr(CT_F_SCT_VERIFY, CT_R_SCT_INVALID_SIGNATURE); end: EVP_MD_CTX_free(ctx); return ret; }
static int ssl_verify_rsa_pss(SSL *ssl, const uint8_t *signature, size_t signature_len, const EVP_MD *md, EVP_PKEY *pkey, const uint8_t *in, size_t in_len) { if (pkey->type != EVP_PKEY_RSA) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); EVP_PKEY_CTX *pctx; int ret = EVP_DigestVerifyInit(&md_ctx, &pctx, md, NULL, pkey) && EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) && EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) && EVP_DigestVerifyUpdate(&md_ctx, in, in_len) && EVP_DigestVerifyFinal(&md_ctx, signature, signature_len); EVP_MD_CTX_cleanup(&md_ctx); return ret; }
static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *sigalg, ASN1_BIT_STRING *str, EVP_PKEY *pkey) { const ASN1_OBJECT *obj; int ptype; int nid; /* Sanity check: make sure it is ED25519/ED448 with absent parameters */ X509_ALGOR_get0(&obj, &ptype, NULL, sigalg); nid = OBJ_obj2nid(obj); if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) { ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING); return 0; } if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey)) return 0; return 2; }
static int test_EVP_DigestVerifyInit(void) { int ret = 0; EVP_PKEY *pkey = NULL; EVP_MD_CTX *md_ctx = NULL; if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()) || !TEST_ptr(pkey = load_example_rsa_key())) goto out; if (!TEST_true(EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, pkey)) || !TEST_true(EVP_DigestVerifyUpdate(md_ctx, kMsg, sizeof(kMsg))) || !TEST_true(EVP_DigestVerifyFinal(md_ctx, kSignature, sizeof(kSignature)))) goto out; ret = 1; out: EVP_MD_CTX_free(md_ctx); EVP_PKEY_free(pkey); return ret; }
static LUA_FUNCTION(openssl_verifyInit) { const EVP_MD *md = get_digest(L, 1); EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); ENGINE* e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL; EVP_PKEY_CTX *pctx = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_create(); luaL_argcheck(L, !openssl_pkey_is_private(pkey), 2, "need public key"); if (ctx) { int ret = EVP_DigestVerifyInit(ctx, &pctx, md, e, pkey); if (ret) { PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); } else return openssl_pushresult(L, ret); } else lua_pushnil(L); return 1; }
int verifySignRSA(EVP_PKEY* key, const unsigned char* sig, const unsigned char* msg, size_t slen, size_t msglen){ EVP_MD_CTX* ctx = NULL; const EVP_MD* md = NULL; if(!msg || !sig || !slen || !key) { return -1; } ctx = EVP_MD_CTX_create(); md = EVP_get_digestbyname(hn); if(md == NULL){ printf("ERR EVP_get_digestbyname\n"); return 0; } if(ctx == NULL){ printf("ERR EVP_MD_CTX_create\n"); return 0; } if(1 != EVP_DigestInit_ex(ctx, md, NULL)){ printf("ERR EVP_DigestInit_ex\n"); return 0; } if(1 != EVP_DigestVerifyInit(ctx, NULL, md, NULL, key)){ printf("ERR EVP_DigestVerifyInit\n"); return 0; } if(1 != EVP_DigestVerifyUpdate(ctx, msg, msglen)){ printf("ERR EVP_DigestVerifyUpdate\n"); return 0; } ERR_clear_error(); return EVP_DigestVerifyFinal(ctx, sig, slen); }
static void check_jwt_signature(const char *b64_signature, RSA *rsa_key, const char *signed_data, size_t signed_data_size) { EVP_MD_CTX *md_ctx = EVP_MD_CTX_create(); EVP_PKEY *key = EVP_PKEY_new(); gpr_slice sig = grpc_base64_decode(b64_signature, 1); GPR_ASSERT(!GPR_SLICE_IS_EMPTY(sig)); GPR_ASSERT(GPR_SLICE_LENGTH(sig) == 128); GPR_ASSERT(md_ctx != NULL); GPR_ASSERT(key != NULL); EVP_PKEY_set1_RSA(key, rsa_key); GPR_ASSERT(EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, key) == 1); GPR_ASSERT(EVP_DigestVerifyUpdate(md_ctx, signed_data, signed_data_size) == 1); GPR_ASSERT(EVP_DigestVerifyFinal(md_ctx, GPR_SLICE_START_PTR(sig), GPR_SLICE_LENGTH(sig)) == 1); gpr_slice_unref(sig); if (key != NULL) EVP_PKEY_free(key); if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); }
bool RSA_PKCS1_verify(Handle<ScopedEVP_PKEY> hKey, const EVP_MD *md, Handle<std::string> hData, Handle<std::string> hSignature) { LOG_FUNC(); ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); EVP_PKEY_CTX* pctx = nullptr; if (ctx.isEmpty() || !EVP_DigestVerifyInit(ctx.Get(), &pctx, md, nullptr, hKey->Get())) { THROW_OPENSSL("EVP_DigestSignInit"); } byte* signature = (byte*)hSignature->c_str(); size_t signaturelen = hSignature->length(); byte* data = (byte*)hData->c_str(); size_t datalen= hData->length(); if (!EVP_DigestVerifyUpdate(ctx.Get(), data, datalen)) { THROW_OPENSSL("EVP_DigestSignUpdate"); } int res = EVP_DigestVerifyFinal(ctx.Get(), signature, signaturelen); return res == 1; }
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) { EVP_MD_CTX ctx; unsigned char *buf_in=NULL; int ret= -1,inl; int mdnid, pknid; if (!pkey) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); return -1; } EVP_MD_CTX_init(&ctx); /* Convert signature OID into digest and public key OIDs */ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } if (mdnid == NID_undef) { if (!pkey->ameth || !pkey->ameth->item_verify) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey); /* Return value of 2 means carry on, anything else means we * exit straight away: either a fatal error of the underlying * verification routine handles all verification. */ if (ret != 2) goto err; ret = -1; } else { const EVP_MD *type; type=EVP_get_digestbynid(mdnid); if (type == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } /* Check public key OID matches public key type */ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE); goto err; } if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } } inl = ASN1_item_i2d(asn, &buf_in, it); if (buf_in == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } OPENSSL_cleanse(buf_in,(unsigned int)inl); OPENSSL_free(buf_in); if (EVP_DigestVerifyFinal(&ctx,signature->data, (size_t)signature->length) <= 0) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } /* we don't need to zero the 'ctx' because we just checked * public information */ /* memset(&ctx,0,sizeof(ctx)); */ ret=1; err: EVP_MD_CTX_cleanup(&ctx); return(ret); }
int main() { int ret = -1; int verbose = 0; BIO *out = NULL; int id = EVP_PKEY_SM2; const EVP_MD *md = EVP_sm3(); ENGINE *engine = NULL; EVP_PKEY_CTX *pkctx = NULL; EVP_PKEY *pkey = NULL; EVP_MD_CTX *mdctx = NULL; EVP_CIPHER_CTX *cpctx = NULL; unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world"; size_t dgstlen = 32; unsigned char sig[256]; size_t siglen = sizeof(sig); unsigned char msg[] = "hello world this is the message"; size_t msglen = sizeof(msg); unsigned char cbuf[512]; size_t cbuflen = sizeof(cbuf); unsigned char mbuf[512]; size_t mbuflen = sizeof(mbuf); int len; unsigned int ulen; ERR_load_crypto_strings(); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (!(pkctx = EVP_PKEY_CTX_new_id(id, engine))) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_PKEY_keygen_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_PKEY_keygen(pkctx, &pkey)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } EVP_PKEY_CTX_free(pkctx); if (0) { EVP_PKEY_print_public(out, pkey, 4, NULL); BIO_printf(out, "\n"); EVP_PKEY_print_private(out, pkey, 4, NULL); BIO_printf(out, "\n"); } if (!(pkctx = EVP_PKEY_CTX_new(pkey, engine))) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_PKEY_sign() */ if (!EVP_PKEY_sign_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } bzero(sig, sizeof(sig)); siglen = sizeof(sig); dgstlen = 32; if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { size_t i; printf("signature (%zu bytes) = ", siglen); for (i = 0; i < siglen; i++) { printf("%02X", sig[i]); } printf("\n"); } if (!EVP_PKEY_verify_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { printf("signature verification success!\n"); } /* EVP_PKEY_encrypt() */ if (!EVP_PKEY_encrypt_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } cbuflen = sizeof(cbuf); if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { size_t i; printf("ciphertext (%zu bytes) = ", cbuflen); for (i = 0; i < cbuflen; i++) { printf("%02X", cbuf[i]); } printf("\n"); } if (!EVP_PKEY_decrypt_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } bzero(mbuf, sizeof(mbuf)); mbuflen = sizeof(mbuf); if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { printf("original message = %s\n", msg); printf("decrypted message = %s\n", mbuf); } /* EVP_PKEY_encrypt_old */ if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { int i; printf("ciphertext (%d bytes) = ", len); for (i = 0; i < len; i++) { printf("%02X", cbuf[i]); } printf("\n"); } bzero(mbuf, sizeof(mbuf)); if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { printf("original message = %s\n", msg); printf("decrypted message = %s\n", mbuf); } if (!(mdctx = EVP_MD_CTX_create())) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_SignInit_ex/Update/Final_ex */ if (!EVP_SignInit_ex(mdctx, EVP_sm3(), engine)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_SignUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_SignFinal(mdctx, sig, &ulen, pkey)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } siglen = ulen; if (verbose) { size_t i; printf("signature (%zu bytes) = ", siglen); for (i = 0; i < siglen; i++) { printf("%02X", sig[i]); } printf("\n"); } if (!EVP_VerifyInit_ex(mdctx, EVP_sm3(), engine)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_VerifyUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (EVP_VerifyFinal(mdctx, sig, ulen, pkey) != SM2_VERIFY_SUCCESS) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_DigestSignInit/Update/Final() */ // FIXME: return values might be different, not just 1 or 0 if (!EVP_DigestSignInit(mdctx, &pkctx, md, engine, pkey)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } siglen = sizeof(sig); if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } pkctx = NULL; if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, engine, pkey)) { ERR_print_errors_fp(stderr); fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_SealInit/Update/Final() EVP_OpenInit/Update/Final() */ /* EVP_PKEY *pk[NUM_PKEYS] = {0}; unsigned char iv[16]; unsigned char ek[NUM_PKEYS][256]; int eklen[NUM_PKEYS]; RAND_pseudo_bytes(iv, sizeof(iv)); int i; for (i = 0; i < NUM_PKEYS; i++) { } if (!(cpctx = EVP_CIPHER_CTX_new())) { goto end; } if (!EVP_SealInit(cpctx, cipher, ek, &ekl, iv, pubk, npubk)) { goto end; } if (!EVP_SealUpdate(cpctx, msg, msglen)) { goto end; } if (!EVP_SealFinal(cpctx, cbuf, (int *)&cbuflen)) { goto end; } */ printf("test success!\n"); ret = 1; end: ERR_print_errors_fp(stderr); return ret; }
static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey) { int rv = -1; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; EVP_PKEY_CTX *pkctx; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS); goto err; } /* Check mask and lookup mask hash algorithm */ if (pss->maskGenAlgorithm) { if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM); goto err; } if (!maskHash) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER); goto err; } mgf1md = EVP_get_digestbyobj(maskHash->algorithm); if (mgf1md == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST); goto err; } } else mgf1md = EVP_sha1(); if (pss->hashAlgorithm) { md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm); if (md == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST); goto err; } } else md = EVP_sha1(); if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH); goto err; } } else saltlen = 20; /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER); goto err; } /* We have all parameters now set up context */ if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; /* Carry on */ rv = 2; err: RSA_PSS_PARAMS_free(pss); if (maskHash) X509_ALGOR_free(maskHash); return rv; }
static int test_EVP_SM2(void) { int ret = 0; EVP_PKEY *pkey = NULL; EVP_PKEY *params = NULL; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY_CTX *kctx = NULL; EVP_PKEY_CTX *sctx = NULL; size_t sig_len = 0; unsigned char *sig = NULL; EVP_MD_CTX *md_ctx = NULL; EVP_MD_CTX *md_ctx_verify = NULL; EVP_PKEY_CTX *cctx = NULL; uint8_t ciphertext[128]; size_t ctext_len = sizeof(ciphertext); uint8_t plaintext[8]; size_t ptext_len = sizeof(plaintext); uint8_t sm2_id[] = {1, 2, 3, 4, 'l', 'e', 't', 't', 'e', 'r'}; pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); if (!TEST_ptr(pctx)) goto done; if (!TEST_true(EVP_PKEY_paramgen_init(pctx) == 1)) goto done; if (!TEST_true(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2))) goto done; if (!TEST_true(EVP_PKEY_paramgen(pctx, ¶ms))) goto done; kctx = EVP_PKEY_CTX_new(params, NULL); if (!TEST_ptr(kctx)) goto done; if (!TEST_true(EVP_PKEY_keygen_init(kctx))) goto done; if (!TEST_true(EVP_PKEY_keygen(kctx, &pkey))) goto done; if (!TEST_true(EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2))) goto done; if (!TEST_ptr(md_ctx = EVP_MD_CTX_new())) goto done; if (!TEST_ptr(md_ctx_verify = EVP_MD_CTX_new())) goto done; if (!TEST_ptr(sctx = EVP_PKEY_CTX_new(pkey, NULL))) goto done; EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx); EVP_MD_CTX_set_pkey_ctx(md_ctx_verify, sctx); if (!TEST_int_gt(EVP_PKEY_CTX_set1_id(sctx, sm2_id, sizeof(sm2_id)), 0)) goto done; if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sm3(), NULL, pkey))) goto done; if(!TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg)))) goto done; /* Determine the size of the signature. */ if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len))) goto done; if (!TEST_size_t_eq(sig_len, (size_t)EVP_PKEY_size(pkey))) goto done; if (!TEST_ptr(sig = OPENSSL_malloc(sig_len))) goto done; if (!TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len))) goto done; /* Ensure that the signature round-trips. */ if (!TEST_true(EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sm3(), NULL, pkey))) goto done; if (!TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg)))) goto done; if (!TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len))) goto done; /* now check encryption/decryption */ if (!TEST_ptr(cctx = EVP_PKEY_CTX_new(pkey, NULL))) goto done; if (!TEST_true(EVP_PKEY_encrypt_init(cctx))) goto done; if (!TEST_true(EVP_PKEY_encrypt(cctx, ciphertext, &ctext_len, kMsg, sizeof(kMsg)))) goto done; if (!TEST_true(EVP_PKEY_decrypt_init(cctx))) goto done; if (!TEST_true(EVP_PKEY_decrypt(cctx, plaintext, &ptext_len, ciphertext, ctext_len))) goto done; if (!TEST_true(ptext_len == sizeof(kMsg))) goto done; if (!TEST_true(memcmp(plaintext, kMsg, sizeof(kMsg)) == 0)) goto done; ret = 1; done: EVP_PKEY_CTX_free(pctx); EVP_PKEY_CTX_free(kctx); EVP_PKEY_CTX_free(sctx); EVP_PKEY_CTX_free(cctx); EVP_PKEY_free(pkey); EVP_PKEY_free(params); EVP_MD_CTX_free(md_ctx); EVP_MD_CTX_free(md_ctx_verify); OPENSSL_free(sig); return ret; }
static int test_EVP_SM2_verify(void) { /* From https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02#appendix-A */ const char *pubkey = "-----BEGIN PUBLIC KEY-----\n" "MIIBMzCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEAhULWnkwETxjouSQ1\n" "v2/33kVyg5FcRVF9ci7biwjx38MwRAQgeHlotPoyw/0kF4Quc7v+/y88hItoMdfg\n" "7GUiizk35JgEIGPkxtOyOwyEnPhCQUhL/kj2HVmlsWugbm4S0donxSSaBEEEQh3r\n" "1hti6rZ0ZDTrw8wxXjIiCzut1QvcTE5sFH/t1D0GgFEry7QsB9RzSdIVO3DE5df9\n" "/L+jbqGoWEG55G4JogIhAIVC1p5MBE8Y6LkkNb9v990pdyBjBIVijVrnTufDLnm3\n" "AgEBA0IABArkx3mKoPEZRxvuEYJb5GICu3nipYRElel8BP9N8lSKfAJA+I8c1OFj\n" "Uqc8F7fxbwc1PlOhdtaEqf4Ma7eY6Fc=\n" "-----END PUBLIC KEY-----\n"; const char *msg = "message digest"; const char *id = "*****@*****.**"; const uint8_t signature[] = { 0x30, 0x44, 0x02, 0x20, 0x40, 0xF1, 0xEC, 0x59, 0xF7, 0x93, 0xD9, 0xF4, 0x9E, 0x09, 0xDC, 0xEF, 0x49, 0x13, 0x0D, 0x41, 0x94, 0xF7, 0x9F, 0xB1, 0xEE, 0xD2, 0xCA, 0xA5, 0x5B, 0xAC, 0xDB, 0x49, 0xC4, 0xE7, 0x55, 0xD1, 0x02, 0x20, 0x6F, 0xC6, 0xDA, 0xC3, 0x2C, 0x5D, 0x5C, 0xF1, 0x0C, 0x77, 0xDF, 0xB2, 0x0F, 0x7C, 0x2E, 0xB6, 0x67, 0xA4, 0x57, 0x87, 0x2F, 0xB0, 0x9E, 0xC5, 0x63, 0x27, 0xA6, 0x7E, 0xC7, 0xDE, 0xEB, 0xE7 }; int rc = 0; BIO *bio = NULL; EVP_PKEY *pkey = NULL; EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; bio = BIO_new_mem_buf(pubkey, strlen(pubkey)); if (!TEST_true(bio != NULL)) goto done; pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); if (!TEST_true(pkey != NULL)) goto done; if (!TEST_true(EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2))) goto done; if (!TEST_ptr(mctx = EVP_MD_CTX_new())) goto done; if (!TEST_ptr(pctx = EVP_PKEY_CTX_new(pkey, NULL))) goto done; if (!TEST_int_gt(EVP_PKEY_CTX_set1_id(pctx, (const uint8_t *)id, strlen(id)), 0)) goto done; EVP_MD_CTX_set_pkey_ctx(mctx, pctx); if (!TEST_true(EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, pkey))) goto done; if (!TEST_true(EVP_DigestVerifyUpdate(mctx, msg, strlen(msg)))) goto done; if (!TEST_true(EVP_DigestVerifyFinal(mctx, signature, sizeof(signature)))) goto done; rc = 1; done: BIO_free(bio); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(pctx); EVP_MD_CTX_free(mctx); return rc; }
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) { EVP_MD_CTX *ctx = NULL; unsigned char *buf_in = NULL; int ret = -1, inl = 0; int mdnid, pknid; if (!pkey) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); return -1; } if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); return -1; } ctx = EVP_MD_CTX_new(); if (ctx == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } /* Convert signature OID into digest and public key OIDs */ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } if (mdnid == NID_undef) { if (!pkey->ameth || !pkey->ameth->item_verify) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey); /* * Return value of 2 means carry on, anything else means we exit * straight away: either a fatal error of the underlying verification * routine handles all verification. */ if (ret != 2) goto err; ret = -1; } else { const EVP_MD *type; type = EVP_get_digestbynid(mdnid); if (type == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } /* Check public key OID matches public key type */ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE); goto err; } if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); ret = 0; goto err; } } inl = ASN1_item_i2d(asn, &buf_in, it); if (buf_in == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } ret = EVP_DigestVerify(ctx, signature->data, (size_t)signature->length, buf_in, inl); if (ret <= 0) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); goto err; } ret = 1; err: OPENSSL_clear_free(buf_in, (unsigned int)inl); EVP_MD_CTX_free(ctx); return ret; }
int PKCS7_signatureVerify_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509, const unsigned char* data, size_t len, int hash) { ASN1_OCTET_STRING *os; const EVP_MD* md; EVP_MD_CTX mdc, mdc_tmp; int ret = 0, i; int md_type; STACK_OF(X509_ATTRIBUTE) *sk; EVP_PKEY *pkey = NULL; EVP_MD_CTX_init(&mdc); EVP_MD_CTX_init(&mdc_tmp); if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } md_type = OBJ_obj2nid(si->digest_alg->algorithm); md = EVP_get_digestbynid(md_type); if (!md || !data || (hash && len != (size_t) md->ctx_size) ) goto err; if (!EVP_DigestInit_ex(&mdc, md, NULL)) goto err; if (hash) memcpy(mdc.md_data, data, len); else EVP_DigestUpdate(&mdc, data, len); pkey = X509_get_pubkey(x509); if (!pkey) { ret = -1; goto err; } /* * mdc is the digest ctx that we want, unless there are attributes, in * which case the digest is the signed attributes */ if (!EVP_MD_CTX_copy_ex(&mdc_tmp, &mdc)) goto err; sk = si->auth_attr; if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; unsigned int md_len; int alen; ASN1_OCTET_STRING *message_digest; if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) goto err; message_digest = PKCS7_digest_from_attributes(sk); if (!message_digest) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } if ((message_digest->length != (int) md_len) || (memcmp(message_digest->data, md_dat, md_len))) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); ret = -1; goto err; } if (!EVP_DigestVerifyInit(&mdc_tmp, NULL, EVP_get_digestbynid(md_type), NULL, pkey)) goto err; alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); if (alen <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); ret = -1; goto err; } if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) goto err; OPENSSL_free(abuf); } os = si->enc_digest; i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); ret = -1; goto err; } else ret = 1; err: EVP_PKEY_free(pkey); EVP_MD_CTX_cleanup(&mdc); EVP_MD_CTX_cleanup(&mdc_tmp); return (ret); }
/* From PSS AlgorithmIdentifier set public key parameters. */ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { int ret = 0; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; EVP_PKEY_CTX *pkctx; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); return 0; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); if (!mgf1md) { goto err; } md = rsa_algor_to_md(pss->hashAlgorithm); if (!md) { goto err; } saltlen = 20; if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH); goto err; } } /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER); goto err; } if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) || !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) || !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) || !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) { goto err; } ret = 1; err: RSA_PSS_PARAMS_free(pss); if (maskHash) { X509_ALGOR_free(maskHash); } return ret; }
/*- * Positive and negative ECDSA testing through EVP interface: * - EVP_DigestSign (this is the one-shot version) * - EVP_DigestVerify * * Tests the library can successfully: * - create a key * - create a signature * - accept that signature * - reject that signature with a different public key * - reject that signature if its length is not correct * - reject that signature after modifying the message * - accept that signature after un-modifying the message * - reject that signature after modifying the signature * - accept that signature after un-modifying the signature */ static int test_builtin(int n) { EC_KEY *eckey_neg = NULL, *eckey = NULL; unsigned char dirt, offset, tbs[128]; unsigned char *sig = NULL; EVP_PKEY *pkey_neg = NULL, *pkey = NULL; EVP_MD_CTX *mctx = NULL; size_t sig_len; int nid, ret = 0; nid = curves[n].nid; /* skip built-in curves where ord(G) is not prime */ if (nid == NID_ipsec4 || nid == NID_ipsec3) { TEST_info("skipped: ECDSA unsupported for curve %s", OBJ_nid2sn(nid)); return 1; } TEST_info("testing ECDSA for curve %s", OBJ_nid2sn(nid)); if (!TEST_ptr(mctx = EVP_MD_CTX_new()) /* get some random message data */ || !TEST_true(RAND_bytes(tbs, sizeof(tbs))) /* real key */ || !TEST_ptr(eckey = EC_KEY_new_by_curve_name(nid)) || !TEST_true(EC_KEY_generate_key(eckey)) || !TEST_ptr(pkey = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey)) /* fake key for negative testing */ || !TEST_ptr(eckey_neg = EC_KEY_new_by_curve_name(nid)) || !TEST_true(EC_KEY_generate_key(eckey_neg)) || !TEST_ptr(pkey_neg = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey_neg, eckey_neg))) goto err; sig_len = ECDSA_size(eckey); if (!TEST_ptr(sig = OPENSSL_malloc(sig_len)) /* create a signature */ || !TEST_true(EVP_DigestSignInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_true(EVP_DigestSign(mctx, sig, &sig_len, tbs, sizeof(tbs))) || !TEST_int_le(sig_len, ECDSA_size(eckey)) /* negative test, verify with wrong key, 0 return */ || !TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey_neg)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0) /* negative test, verify with wrong signature length, -1 return */ || !TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len - 1, tbs, sizeof(tbs)), -1) /* positive test, verify with correct key, 1 return */ || !TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; /* muck with the message, test it fails with 0 return */ tbs[0] ^= 1; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0)) goto err; /* un-muck and test it verifies */ tbs[0] ^= 1; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; /*- * Muck with the ECDSA signature. The DER encoding is one of: * - 30 LL 02 .. * - 30 81 LL 02 .. * * - Sometimes this mucks with the high level DER sequence wrapper: * in that case, DER-parsing of the whole signature should fail. * * - Sometimes this mucks with the DER-encoding of ECDSA.r: * in that case, DER-parsing of ECDSA.r should fail. * * - Sometimes this mucks with the DER-encoding of ECDSA.s: * in that case, DER-parsing of ECDSA.s should fail. * * - Sometimes this mucks with ECDSA.r: * in that case, the signature verification should fail. * * - Sometimes this mucks with ECDSA.s: * in that case, the signature verification should fail. * * The usual case is changing the integer value of ECDSA.r or ECDSA.s. * Because the ratio of DER overhead to signature bytes is small. * So most of the time it will be one of the last two cases. * * In any case, EVP_PKEY_verify should not return 1 for valid. */ offset = tbs[0] % sig_len; dirt = tbs[1] ? tbs[1] : 1; sig[offset] ^= dirt; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_ne(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; /* un-muck and test it verifies */ sig[offset] ^= dirt; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; ret = 1; err: EVP_PKEY_free(pkey); EVP_PKEY_free(pkey_neg); EVP_MD_CTX_free(mctx); OPENSSL_free(sig); return ret; }
sgx_status_t sgx_rsa3072_verify(const uint8_t *p_data, uint32_t data_size, const sgx_rsa3072_public_key_t *p_public, const sgx_rsa3072_signature_t *p_signature, sgx_rsa_result_t *p_result) { if ((p_data == NULL) || (data_size < 1) || (p_public == NULL) || (p_signature == NULL) || (p_result == NULL)) { return SGX_ERROR_INVALID_PARAMETER; } *p_result = SGX_RSA_INVALID_SIGNATURE; sgx_status_t retval = SGX_ERROR_UNEXPECTED; int verified = 0; RSA *pub_rsa_key = NULL; EVP_PKEY *pub_pkey = NULL; BIGNUM *n = NULL; BIGNUM *e = NULL; const EVP_MD* sha256_md = NULL; EVP_MD_CTX *ctx = NULL; CLEAR_OPENSSL_ERROR_QUEUE; do { // converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM // n = BN_lebin2bn((const unsigned char *)p_public->mod, sizeof(p_public->mod), 0); if (n == NULL) { break; } // converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM // e = BN_lebin2bn((const unsigned char *)p_public->exp, sizeof(p_public->exp), 0); if (e == NULL) { break; } // allocates and initializes an RSA key structure // pub_rsa_key = RSA_new(); if (pub_rsa_key == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // sets the modulus and public exp values of the RSA key // if (RSA_set0_key(pub_rsa_key, n, e, NULL) != 1) { BN_clear_free(n); BN_clear_free(e); break; } // allocates an empty EVP_PKEY structure // pub_pkey = EVP_PKEY_new(); if (pub_pkey == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed // if (EVP_PKEY_assign_RSA(pub_pkey, pub_rsa_key) != 1) { RSA_free(pub_rsa_key); break; } // allocates, initializes and returns a digest context // ctx = EVP_MD_CTX_new(); if (ctx == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // return EVP_MD structures for SHA256 digest algorithm */ // sha256_md = EVP_sha256(); if (sha256_md == NULL) { break; } // sets up verification context ctx to use digest type // if (EVP_DigestVerifyInit(ctx, NULL, sha256_md, NULL, pub_pkey) <= 0) { break; } // hashes data_size bytes of data at p_data into the verification context ctx. // this function can be called several times on the same ctx to hash additional data // if (EVP_DigestVerifyUpdate(ctx, (const void *)p_data, data_size) <= 0) { break; } // verifies the data in ctx against the signature in p_signature of length SGX_RSA3072_KEY_SIZE // verified = EVP_DigestVerifyFinal(ctx, (const unsigned char *)p_signature, SGX_RSA3072_KEY_SIZE); if (verified) { *p_result = SGX_RSA_VALID; } else if (verified != 0) { break; } retval = SGX_SUCCESS; } while (0); if (retval != SGX_SUCCESS) { GET_LAST_OPENSSL_ERROR; } if (ctx) EVP_MD_CTX_free(ctx); if (pub_pkey) { EVP_PKEY_free(pub_pkey); pub_rsa_key = NULL; n = NULL; e = NULL; } if (pub_rsa_key) { RSA_free(pub_rsa_key); n = NULL; e = NULL; } if (n) BN_clear_free(n); if (e) BN_clear_free(e); return retval; }
int dgst_main(int argc, char **argv) { BIO *in = NULL, *inp, *bmd = NULL, *out = NULL; ENGINE *e = NULL, *impl = NULL; EVP_PKEY *sigkey = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; char *hmac_key = NULL; char *mac_name = NULL; char *passinarg = NULL, *passin = NULL; const EVP_MD *md = NULL, *m; const char *outfile = NULL, *keyfile = NULL, *prog = NULL; const char *sigfile = NULL, *randfile = NULL; OPTION_CHOICE o; int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0, non_fips_allow = 0; unsigned char *buf = NULL, *sigbuf = NULL; int engine_impl = 0; prog = opt_progname(argv[0]); buf = app_malloc(BUFSIZE, "I/O buffer"); md = EVP_get_digestbyname(prog); prog = opt_init(argc, argv, dgst_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(dgst_options); ret = 0; goto end; case OPT_C: separator = 1; break; case OPT_R: separator = 2; break; case OPT_RAND: randfile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_SIGN: keyfile = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_VERIFY: keyfile = opt_arg(); want_pub = do_verify = 1; break; case OPT_PRVERIFY: keyfile = opt_arg(); do_verify = 1; break; case OPT_SIGNATURE: sigfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_ENGINE_IMPL: engine_impl = 1; break; case OPT_HEX: out_bin = 0; break; case OPT_BINARY: out_bin = 1; break; case OPT_DEBUG: debug = 1; break; case OPT_FIPS_FINGERPRINT: hmac_key = "etaonrishdlcupfm"; break; case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; break; case OPT_HMAC: hmac_key = opt_arg(); break; case OPT_MAC: mac_name = opt_arg(); break; case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; case OPT_MACOPT: if (!macopts) macopts = sk_OPENSSL_STRING_new_null(); if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) goto opthelp; break; case OPT_DIGEST: if (!opt_md(opt_unknown(), &m)) goto opthelp; md = m; break; } } argc = opt_num_rest(); argv = opt_rest(); if (do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); goto end; } if (engine_impl) impl = e; in = BIO_new(BIO_s_file()); bmd = BIO_new(BIO_f_md()); if ((in == NULL) || (bmd == NULL)) { ERR_print_errors(bio_err); goto end; } if (debug) { BIO_set_callback(in, BIO_debug_callback); /* needed for windows 3.1 */ BIO_set_callback_arg(in, (char *)bio_err); } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (out_bin == -1) { if (keyfile) out_bin = 1; else out_bin = 0; } if (randfile) app_RAND_load_file(randfile, 0); out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); if (out == NULL) goto end; if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) { BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); goto end; } if (keyfile) { if (want_pub) sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); else sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); if (!sigkey) { /* * load_[pub]key() has already printed an appropriate message */ goto end; } } if (mac_name) { EVP_PKEY_CTX *mac_ctx = NULL; int r = 0; if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) goto mac_end; if (macopts) { char *macopt; for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { macopt = sk_OPENSSL_STRING_value(macopts, i); if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt); ERR_print_errors(bio_err); goto mac_end; } } } if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto mac_end; } r = 1; mac_end: EVP_PKEY_CTX_free(mac_ctx); if (r == 0) goto end; } if (non_fips_allow) { EVP_MD_CTX *md_ctx; BIO_get_md_ctx(bmd, &md_ctx); EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } if (hmac_key) { sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl, (unsigned char *)hmac_key, -1); if (!sigkey) goto end; } if (sigkey) { EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; int r; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (do_verify) r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); else r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); if (!r) { BIO_printf(bio_err, "Error setting context\n"); ERR_print_errors(bio_err); goto end; } if (sigopts) { char *sigopt; for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { sigopt = sk_OPENSSL_STRING_value(sigopts, i); if (pkey_ctrl_string(pctx, sigopt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); ERR_print_errors(bio_err); goto end; } } } } /* we use md as a filter, reading from 'in' */ else { EVP_MD_CTX *mctx = NULL; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (md == NULL) md = EVP_md5(); if (!EVP_DigestInit_ex(mctx, md, impl)) { BIO_printf(bio_err, "Error setting digest\n"); ERR_print_errors(bio_err); goto end; } } if (sigfile && sigkey) { BIO *sigbio = BIO_new_file(sigfile, "rb"); if (!sigbio) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } siglen = EVP_PKEY_size(sigkey); sigbuf = app_malloc(siglen, "signature buffer"); siglen = BIO_read(sigbio, sigbuf, siglen); BIO_free(sigbio); if (siglen <= 0) { BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } } inp = BIO_push(bmd, in); if (md == NULL) { EVP_MD_CTX *tctx; BIO_get_md_ctx(bmd, &tctx); md = EVP_MD_CTX_md(tctx); } if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, NULL, NULL, "stdin", bmd); } else { const char *md_name = NULL, *sig_name = NULL; if (!out_bin) { if (sigkey) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_get0_asn1(sigkey); if (ameth) EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &sig_name, ameth); } if (md) md_name = EVP_MD_name(md); } ret = 0; for (i = 0; i < argc; i++) { int r; if (BIO_read_filename(in, argv[i]) <= 0) { perror(argv[i]); ret++; continue; } else r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, sig_name, md_name, argv[i], bmd); if (r) ret = r; (void)BIO_reset(bmd); } } end: OPENSSL_clear_free(buf, BUFSIZE); BIO_free(in); OPENSSL_free(passin); BIO_free_all(out); EVP_PKEY_free(sigkey); sk_OPENSSL_STRING_free(sigopts); sk_OPENSSL_STRING_free(macopts); OPENSSL_free(sigbuf); BIO_free(bmd); return (ret); }
int verify_it(const byte* msg, size_t mlen, const byte* sig, size_t slen, EVP_PKEY* pkey) { /* Returned to caller */ int result = -1; if(!msg || !mlen || !sig || !slen || !pkey) { assert(0); return -1; } EVP_MD_CTX* ctx = NULL; do { ctx = EVP_MD_CTX_create(); assert(ctx != NULL); if(ctx == NULL) { printf("EVP_MD_CTX_create failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } const EVP_MD* md = EVP_get_digestbyname(hn); assert(md != NULL); if(md == NULL) { printf("EVP_get_digestbyname failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } int rc = EVP_DigestInit_ex(ctx, md, NULL); assert(rc == 1); if(rc != 1) { printf("EVP_DigestInit_ex failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } rc = EVP_DigestVerifyInit(ctx, NULL, md, NULL, pkey); assert(rc == 1); if(rc != 1) { printf("EVP_DigestVerifyInit failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } rc = EVP_DigestVerifyUpdate(ctx, msg, mlen); assert(rc == 1); if(rc != 1) { printf("EVP_DigestVerifyUpdate failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } /* Clear any errors for the call below */ ERR_clear_error(); rc = EVP_DigestVerifyFinal(ctx, sig, slen); assert(rc == 1); if(rc != 1) { printf("EVP_DigestVerifyFinal failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } result = 0; } while(0); if(ctx) { EVP_MD_CTX_destroy(ctx); ctx = NULL; } return !!result; }
bool find_server(EVP_PKEY *pk, sockaddr6 *addr, uint32_t usecs, uint32_t retries) { bool ok = false; interface ifs[16]; ssize_t count = active_interfaces(ifs, 16); if (count <= 0) return false; addr->sin6_family = AF_INET6; addr->sin6_port = htons(atoi(MCAST_PORT)); addr->sin6_scope_id = ifs[0].index; inet_pton(AF_INET6, MCAST_HOST, &addr->sin6_addr); int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fd == -1) return false; struct ipv6_mreq req = { .ipv6mr_interface = ifs[0].index }; memcpy(&req.ipv6mr_multiaddr, &addr->sin6_addr, sizeof(struct in6_addr)); if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &req, sizeof(req))) { return false; } struct timeval timeout = { .tv_usec = usecs / retries }; setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); sockaddr6 from6; socklen_t from_len = sizeof(from6); sockaddr *from = (sockaddr *) &from6; uint8_t ping[PING_LEN]; struct pong pong; ssize_t len; RAND_bytes(ping, PING_LEN); for (uint32_t i = 0; !ok && i < retries; i++) { EVP_MD_CTX ctx; sendto(fd, ping, PING_LEN, 0, (sockaddr *) addr, sizeof(*addr)); if ((len = recvfrom(fd, &pong, sizeof(pong), 0, from, &from_len)) > 0) { EVP_MD_CTX_init(&ctx); EVP_DigestVerifyInit(&ctx, NULL, EVP_sha256(), NULL, pk); EVP_DigestVerifyUpdate(&ctx, &ping, PING_LEN); EVP_DigestVerifyUpdate(&ctx, &pong, PONG_LEN); if (EVP_DigestVerifyFinal(&ctx, pong.sig, len) == 1) { memcpy(addr->sin6_addr.s6_addr, &pong.addr, 16); addr->sin6_port = pong.port; ok = true; } EVP_MD_CTX_cleanup(&ctx); } } close(fd); return ok; } int mcast_sock(interface *ifa, sockaddr6 *addr, char *host) { struct ipv6_mreq req = { .ipv6mr_interface = ifa->index }; inet_pton(AF_INET6, host, &req.ipv6mr_multiaddr); int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fd == -1 || bind(fd, (sockaddr *) addr, sizeof(*addr))) goto error; if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &req, sizeof(req))) goto error; return fd; error: if (fd >= 0) close(fd); return -1; } char *name(sockaddr6 *addr, socklen_t len) { static char host[NI_MAXHOST]; int flags = NI_NUMERICHOST; getnameinfo((struct sockaddr *) addr, len, host, NI_MAXHOST, NULL, 0, flags); return host; }
int dgst_main(int argc, char **argv) { ENGINE *e = NULL; unsigned char *buf = NULL; int i, err = 1; const EVP_MD *md = NULL, *m; BIO *in = NULL, *inp; BIO *bmd = NULL; BIO *out = NULL; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE + 1]; int separator = 0; int debug = 0; int keyform = FORMAT_PEM; const char *outfile = NULL, *keyfile = NULL; const char *sigfile = NULL; int out_bin = -1, want_pub = 0, do_verify = 0; EVP_PKEY *sigkey = NULL; unsigned char *sigbuf = NULL; int siglen = 0; char *passargin = NULL, *passin = NULL; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif char *hmac_key = NULL; char *mac_name = NULL; STACK_OF(OPENSSL_STRING) * sigopts = NULL, *macopts = NULL; if ((buf = malloc(BUFSIZE)) == NULL) { BIO_printf(bio_err, "out of memory\n"); goto end; } /* first check the program name */ program_name(argv[0], pname, sizeof pname); md = EVP_get_digestbyname(pname); argc--; argv++; while (argc > 0) { if ((*argv)[0] != '-') break; if (strcmp(*argv, "-c") == 0) separator = 1; else if (strcmp(*argv, "-r") == 0) separator = 2; else if (strcmp(*argv, "-out") == 0) { if (--argc < 1) break; outfile = *(++argv); } else if (strcmp(*argv, "-sign") == 0) { if (--argc < 1) break; keyfile = *(++argv); } else if (!strcmp(*argv, "-passin")) { if (--argc < 1) break; passargin = *++argv; } else if (strcmp(*argv, "-verify") == 0) { if (--argc < 1) break; keyfile = *(++argv); want_pub = 1; do_verify = 1; } else if (strcmp(*argv, "-prverify") == 0) { if (--argc < 1) break; keyfile = *(++argv); do_verify = 1; } else if (strcmp(*argv, "-signature") == 0) { if (--argc < 1) break; sigfile = *(++argv); } else if (strcmp(*argv, "-keyform") == 0) { if (--argc < 1) break; keyform = str2fmt(*(++argv)); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) break; engine = *(++argv); e = setup_engine(bio_err, engine, 0); } #endif else if (strcmp(*argv, "-hex") == 0) out_bin = 0; else if (strcmp(*argv, "-binary") == 0) out_bin = 1; else if (strcmp(*argv, "-d") == 0) debug = 1; else if (!strcmp(*argv, "-hmac")) { if (--argc < 1) break; hmac_key = *++argv; } else if (!strcmp(*argv, "-mac")) { if (--argc < 1) break; mac_name = *++argv; } else if (strcmp(*argv, "-sigopt") == 0) { if (--argc < 1) break; if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) break; } else if (strcmp(*argv, "-macopt") == 0) { if (--argc < 1) break; if (!macopts) macopts = sk_OPENSSL_STRING_new_null(); if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) break; } else if ((m = EVP_get_digestbyname(&((*argv)[1]))) != NULL) md = m; else break; argc--; argv++; } if (do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); goto end; } if ((argc > 0) && (argv[0][0] == '-')) { /* bad option */ BIO_printf(bio_err, "unknown option '%s'\n", *argv); BIO_printf(bio_err, "options are\n"); BIO_printf(bio_err, "-c to output the digest with separating colons\n"); BIO_printf(bio_err, "-r to output the digest in coreutils format\n"); BIO_printf(bio_err, "-d to output debug info\n"); BIO_printf(bio_err, "-hex output as hex dump\n"); BIO_printf(bio_err, "-binary output in binary form\n"); BIO_printf(bio_err, "-sign file sign digest using private key in file\n"); BIO_printf(bio_err, "-verify file verify a signature using public key in file\n"); BIO_printf(bio_err, "-prverify file verify a signature using private key in file\n"); BIO_printf(bio_err, "-keyform arg key file format (PEM or ENGINE)\n"); BIO_printf(bio_err, "-out filename output to filename rather than stdout\n"); BIO_printf(bio_err, "-signature file signature to verify\n"); BIO_printf(bio_err, "-sigopt nm:v signature parameter\n"); BIO_printf(bio_err, "-hmac key create hashed MAC with key\n"); BIO_printf(bio_err, "-mac algorithm create MAC (not neccessarily HMAC)\n"); BIO_printf(bio_err, "-macopt nm:v MAC algorithm parameters or key\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif EVP_MD_do_all_sorted(list_md_fn, bio_err); goto end; } in = BIO_new(BIO_s_file()); bmd = BIO_new(BIO_f_md()); if (in == NULL || bmd == NULL) { ERR_print_errors(bio_err); goto end; } if (debug) { BIO_set_callback(in, BIO_debug_callback); /* needed for windows 3.1 */ BIO_set_callback_arg(in, (char *) bio_err); } if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (out_bin == -1) { if (keyfile) out_bin = 1; else out_bin = 0; } if (outfile) { if (out_bin) out = BIO_new_file(outfile, "wb"); else out = BIO_new_file(outfile, "w"); } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } if (!out) { BIO_printf(bio_err, "Error opening output file %s\n", outfile ? outfile : "(stdout)"); ERR_print_errors(bio_err); goto end; } if ((!!mac_name + !!keyfile + !!hmac_key) > 1) { BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); goto end; } if (keyfile) { if (want_pub) sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, e, "key file"); else sigkey = load_key(bio_err, keyfile, keyform, 0, passin, e, "key file"); if (!sigkey) { /* * load_[pub]key() has already printed an appropriate * message */ goto end; } } if (mac_name) { EVP_PKEY_CTX *mac_ctx = NULL; int r = 0; if (!init_gen_str(bio_err, &mac_ctx, mac_name, e, 0)) goto mac_end; if (macopts) { char *macopt; for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { macopt = sk_OPENSSL_STRING_value(macopts, i); if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt); ERR_print_errors(bio_err); goto mac_end; } } } if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto mac_end; } r = 1; mac_end: if (mac_ctx) EVP_PKEY_CTX_free(mac_ctx); if (r == 0) goto end; } if (hmac_key) { sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e, (unsigned char *) hmac_key, -1); if (!sigkey) goto end; } if (sigkey) { EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; int r; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (do_verify) r = EVP_DigestVerifyInit(mctx, &pctx, md, NULL, sigkey); else r = EVP_DigestSignInit(mctx, &pctx, md, NULL, sigkey); if (!r) { BIO_printf(bio_err, "Error setting context\n"); ERR_print_errors(bio_err); goto end; } if (sigopts) { char *sigopt; for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { sigopt = sk_OPENSSL_STRING_value(sigopts, i); if (pkey_ctrl_string(pctx, sigopt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); ERR_print_errors(bio_err); goto end; } } } } /* we use md as a filter, reading from 'in' */ else { if (md == NULL) md = EVP_md5(); if (!BIO_set_md(bmd, md)) { BIO_printf(bio_err, "Error setting digest %s\n", pname); ERR_print_errors(bio_err); goto end; } } if (sigfile && sigkey) { BIO *sigbio; siglen = EVP_PKEY_size(sigkey); sigbuf = malloc(siglen); if (sigbuf == NULL) { BIO_printf(bio_err, "out of memory\n"); ERR_print_errors(bio_err); goto end; } sigbio = BIO_new_file(sigfile, "rb"); if (!sigbio) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } siglen = BIO_read(sigbio, sigbuf, siglen); BIO_free(sigbio); if (siglen <= 0) { BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } } inp = BIO_push(bmd, in); if (md == NULL) { EVP_MD_CTX *tctx; BIO_get_md_ctx(bmd, &tctx); md = EVP_MD_CTX_md(tctx); } if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); err = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, NULL, NULL, "stdin", bmd); } else { const char *md_name = NULL, *sig_name = NULL; if (!out_bin) { if (sigkey) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_get0_asn1(sigkey); if (ameth) EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &sig_name, ameth); } md_name = EVP_MD_name(md); } err = 0; for (i = 0; i < argc; i++) { int r; if (BIO_read_filename(in, argv[i]) <= 0) { perror(argv[i]); err++; continue; } else { r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, sig_name, md_name, argv[i], bmd); } if (r) err = r; (void) BIO_reset(bmd); } } end: if (buf != NULL) { OPENSSL_cleanse(buf, BUFSIZE); free(buf); } if (in != NULL) BIO_free(in); free(passin); BIO_free_all(out); EVP_PKEY_free(sigkey); if (sigopts) sk_OPENSSL_STRING_free(sigopts); if (macopts) sk_OPENSSL_STRING_free(macopts); free(sigbuf); if (bmd != NULL) BIO_free(bmd); return (err); }
/** * Check a canonical sig+rrset and signature against a dnskey * @param buf: buffer with data to verify, the first rrsig part and the * canonicalized rrset. * @param algo: DNSKEY algorithm. * @param sigblock: signature rdata field from RRSIG * @param sigblock_len: length of sigblock data. * @param key: public key data from DNSKEY RR. * @param keylen: length of keydata. * @param reason: bogus reason in more detail. * @return secure if verification succeeded, bogus on crypto failure, * unchecked on format errors and alloc failures. */ enum sec_status verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen, char** reason) { const EVP_MD *digest_type; EVP_MD_CTX* ctx; int res, dofree = 0, docrypto_free = 0; EVP_PKEY *evp_key = NULL; #ifndef USE_DSA if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) return sec_status_secure; #endif #ifndef USE_SHA1 if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) return sec_status_secure; #endif if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { verbose(VERB_QUERY, "verify: failed to setup key"); *reason = "use of key for crypto failed"; EVP_PKEY_free(evp_key); return sec_status_bogus; } #ifdef USE_DSA /* if it is a DSA signature in bind format, convert to DER format */ if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && sigblock_len == 1+2*SHA_DIGEST_LENGTH) { if(!setup_dsa_sig(&sigblock, &sigblock_len)) { verbose(VERB_QUERY, "verify: failed to setup DSA sig"); *reason = "use of key for DSA crypto failed"; EVP_PKEY_free(evp_key); return sec_status_bogus; } docrypto_free = 1; } #endif #if defined(USE_ECDSA) && defined(USE_DSA) else #endif #ifdef USE_ECDSA if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { /* EVP uses ASN prefix on sig, which is not in the wire data */ if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); *reason = "use of signature for ECDSA crypto failed"; EVP_PKEY_free(evp_key); return sec_status_bogus; } dofree = 1; } #endif /* USE_ECDSA */ /* do the signature cryptography work */ #ifdef HAVE_EVP_MD_CTX_NEW ctx = EVP_MD_CTX_new(); #else ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx)); if(ctx) EVP_MD_CTX_init(ctx); #endif if(!ctx) { log_err("EVP_MD_CTX_new: malloc failure"); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); else if(docrypto_free) OPENSSL_free(sigblock); return sec_status_unchecked; } #ifndef HAVE_EVP_DIGESTVERIFY if(EVP_DigestInit(ctx, digest_type) == 0) { verbose(VERB_QUERY, "verify: EVP_DigestInit failed"); #ifdef HAVE_EVP_MD_CTX_NEW EVP_MD_CTX_destroy(ctx); #else EVP_MD_CTX_cleanup(ctx); free(ctx); #endif EVP_PKEY_free(evp_key); if(dofree) free(sigblock); else if(docrypto_free) OPENSSL_free(sigblock); return sec_status_unchecked; } if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf)) == 0) { verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed"); #ifdef HAVE_EVP_MD_CTX_NEW EVP_MD_CTX_destroy(ctx); #else EVP_MD_CTX_cleanup(ctx); free(ctx); #endif EVP_PKEY_free(evp_key); if(dofree) free(sigblock); else if(docrypto_free) OPENSSL_free(sigblock); return sec_status_unchecked; } res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key); #else /* HAVE_EVP_DIGESTVERIFY */ if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) { verbose(VERB_QUERY, "verify: EVP_DigestVerifyInit failed"); #ifdef HAVE_EVP_MD_CTX_NEW EVP_MD_CTX_destroy(ctx); #else EVP_MD_CTX_cleanup(ctx); free(ctx); #endif EVP_PKEY_free(evp_key); if(dofree) free(sigblock); else if(docrypto_free) OPENSSL_free(sigblock); return sec_status_unchecked; } res = EVP_DigestVerify(ctx, sigblock, sigblock_len, (unsigned char*)sldns_buffer_begin(buf), sldns_buffer_limit(buf)); #endif #ifdef HAVE_EVP_MD_CTX_NEW EVP_MD_CTX_destroy(ctx); #else EVP_MD_CTX_cleanup(ctx); free(ctx); #endif EVP_PKEY_free(evp_key); if(dofree) free(sigblock); else if(docrypto_free) OPENSSL_free(sigblock); if(res == 1) { return sec_status_secure; } else if(res == 0) { verbose(VERB_QUERY, "verify: signature mismatch"); *reason = "signature crypto failed"; return sec_status_bogus; } log_crypto_error("verify:", ERR_get_error()); return sec_status_unchecked; }
static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx, const EVP_MD *md, EVP_PKEY *pkey, BIO *in, unsigned char *sig, int siglen, unsigned char **out, size_t *poutlen) { int rv = 0; EVP_MD_CTX *mctx = NULL; unsigned char tbuf[TBUF_MAXSIZE]; int tbuf_len = 0; if ((mctx = EVP_MD_CTX_new()) == NULL) { BIO_printf(bio_err, "Error: out of memory\n"); return rv; } EVP_MD_CTX_set_pkey_ctx(mctx, ctx); switch(pkey_op) { case EVP_PKEY_OP_VERIFY: if (EVP_DigestVerifyInit(mctx, NULL, md, NULL, pkey) != 1) goto end; for (;;) { tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); if (tbuf_len == 0) break; if (tbuf_len < 0) { BIO_printf(bio_err, "Error reading raw input data\n"); goto end; } rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)tbuf_len); if (rv != 1) { BIO_printf(bio_err, "Error verifying raw input data\n"); goto end; } } rv = EVP_DigestVerifyFinal(mctx, sig, (size_t)siglen); break; case EVP_PKEY_OP_SIGN: if (EVP_DigestSignInit(mctx, NULL, md, NULL, pkey) != 1) goto end; for (;;) { tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); if (tbuf_len == 0) break; if (tbuf_len < 0) { BIO_printf(bio_err, "Error reading raw input data\n"); goto end; } rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)tbuf_len); if (rv != 1) { BIO_printf(bio_err, "Error signing raw input data\n"); goto end; } } rv = EVP_DigestSignFinal(mctx, NULL, poutlen); if (rv == 1 && out != NULL) { *out = app_malloc(*poutlen, "buffer output"); rv = EVP_DigestSignFinal(mctx, *out, poutlen); } break; } end: EVP_MD_CTX_free(mctx); return rv; }
static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { int rv = -1; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); if (!mgf1md) goto err; md = rsa_algor_to_md(pss->hashAlgorithm); if (!md) goto err; if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* * Could perform more salt length sanity checks but the main RSA * routines will trap other invalid values anyway. */ if (saltlen < 0) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH); goto err; } } else saltlen = 20; /* * low-level routines support only trailer field 0xbc (value 1) and * PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER); goto err; } /* We have all parameters now set up context */ if (pkey) { if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) goto err; } else { const EVP_MD *checkmd; if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) goto err; if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); goto err; } } if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; /* Carry on */ rv = 1; err: RSA_PSS_PARAMS_free(pss); X509_ALGOR_free(maskHash); return rv; }
int jwt_verify_sha_pem(jwt_t *jwt, const char *head, const char *sig_b64) { unsigned char *sig = NULL; EVP_MD_CTX *mdctx = NULL; ECDSA_SIG *ec_sig = NULL; BIGNUM *ec_sig_r = NULL; BIGNUM *ec_sig_s = NULL; EVP_PKEY *pkey = NULL; const EVP_MD *alg; int type; int pkey_type; BIO *bufkey = NULL; int ret = 0; int slen; switch (jwt->alg) { /* RSA */ case JWT_ALG_RS256: alg = EVP_sha256(); type = EVP_PKEY_RSA; break; case JWT_ALG_RS384: alg = EVP_sha384(); type = EVP_PKEY_RSA; break; case JWT_ALG_RS512: alg = EVP_sha512(); type = EVP_PKEY_RSA; break; /* ECC */ case JWT_ALG_ES256: alg = EVP_sha256(); type = EVP_PKEY_EC; break; case JWT_ALG_ES384: alg = EVP_sha384(); type = EVP_PKEY_EC; break; case JWT_ALG_ES512: alg = EVP_sha512(); type = EVP_PKEY_EC; break; default: return EINVAL; } sig = jwt_b64_decode(sig_b64, &slen); if (sig == NULL) VERIFY_ERROR(EINVAL); bufkey = BIO_new_mem_buf(jwt->key, jwt->key_len); if (bufkey == NULL) VERIFY_ERROR(ENOMEM); /* This uses OpenSSL's default passphrase callback if needed. The * library caller can override this in many ways, all of which are * outside of the scope of LibJWT and this is documented in jwt.h. */ pkey = PEM_read_bio_PUBKEY(bufkey, NULL, NULL, NULL); if (pkey == NULL) VERIFY_ERROR(EINVAL); pkey_type = EVP_PKEY_id(pkey); if (pkey_type != type) VERIFY_ERROR(EINVAL); /* Convert EC sigs back to ASN1. */ if (pkey_type == EVP_PKEY_EC) { unsigned int degree, bn_len; unsigned char *p; EC_KEY *ec_key; ec_sig = ECDSA_SIG_new(); if (ec_sig == NULL) VERIFY_ERROR(ENOMEM); /* Get the actual ec_key */ ec_key = EVP_PKEY_get1_EC_KEY(pkey); if (ec_key == NULL) VERIFY_ERROR(ENOMEM); degree = EC_GROUP_get_degree(EC_KEY_get0_group(ec_key)); EC_KEY_free(ec_key); bn_len = (degree + 7) / 8; if ((bn_len * 2) != slen) VERIFY_ERROR(EINVAL); ec_sig_r = BN_bin2bn(sig, bn_len, NULL); ec_sig_s = BN_bin2bn(sig + bn_len, bn_len, NULL); if (ec_sig_r == NULL || ec_sig_s == NULL) VERIFY_ERROR(EINVAL); ECDSA_SIG_set0(ec_sig, ec_sig_r, ec_sig_s); free(sig); slen = i2d_ECDSA_SIG(ec_sig, NULL); sig = malloc(slen); if (sig == NULL) VERIFY_ERROR(ENOMEM); p = sig; slen = i2d_ECDSA_SIG(ec_sig, &p); if (slen == 0) VERIFY_ERROR(EINVAL); } mdctx = EVP_MD_CTX_create(); if (mdctx == NULL) VERIFY_ERROR(ENOMEM); /* Initialize the DigestVerify operation using alg */ if (EVP_DigestVerifyInit(mdctx, NULL, alg, NULL, pkey) != 1) VERIFY_ERROR(EINVAL); /* Call update with the message */ if (EVP_DigestVerifyUpdate(mdctx, head, strlen(head)) != 1) VERIFY_ERROR(EINVAL); /* Now check the sig for validity. */ if (EVP_DigestVerifyFinal(mdctx, sig, slen) != 1) VERIFY_ERROR(EINVAL); jwt_verify_sha_pem_done: if (bufkey) BIO_free(bufkey); if (pkey) EVP_PKEY_free(pkey); if (mdctx) EVP_MD_CTX_destroy(mdctx); if (sig) free(sig); if (ec_sig) ECDSA_SIG_free(ec_sig); return ret; }