static int verify(char *file,void *in,int ilen,void *sig,int slen) { int r=FILEFAIL; BIO *cert; X509 *x509; EVP_PKEY *key; EVP_MD_CTX *mdc; if(!(cert=BIO_new(BIO_s_file())))goto err1; if(BIO_read_filename(cert,file)<=0)goto err2; r=CRYPTOFAIL; if(!(x509=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL)))goto err2; if(!(key=X509_get_pubkey(x509)))goto err3; if(!(mdc=EVP_MD_CTX_create()))goto err4; if(EVP_DigestInit_ex(mdc,EVP_sha256(),NULL)!=1)goto err5; if(EVP_DigestVerifyInit(mdc,NULL,EVP_sha256(),NULL,key)!=1)goto err5; if(EVP_DigestVerifyUpdate(mdc,in,ilen)!=1)goto err5; if(EVP_DigestVerifyFinal(mdc,sig,slen)!=1)goto err5; r=OK; err5: EVP_MD_CTX_destroy(mdc); err4: EVP_PKEY_free(key); err3: X509_free(x509); err2: BIO_free(cert); err1: return r; }
static int ssl_verify_ecdsa(SSL *ssl, const uint8_t *signature, size_t signature_len, int curve, const EVP_MD *md, EVP_PKEY *pkey, const uint8_t *in, size_t in_len) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); if (ec_key == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* In TLS 1.3, the curve is also specified by the signature algorithm. */ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION && (curve == NID_undef || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) { 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; }
soter_status_t soter_verify_update_rsa_pss_pkcs8(soter_sign_ctx_t* ctx, const void* data, const size_t data_length) { if(!EVP_DigestVerifyUpdate(ctx->md_ctx, data, data_length)){ return SOTER_FAIL; } return SOTER_SUCCESS; }
static int test_EVP_DigestVerifyInit(void) { int ret = 0; EVP_PKEY *pkey = NULL; EVP_MD_CTX *md_ctx; md_ctx = EVP_MD_CTX_new(); pkey = load_example_rsa_key(); if (pkey == NULL || !EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) || !EVP_DigestVerifyUpdate(md_ctx, kMsg, sizeof(kMsg)) || !EVP_DigestVerifyFinal(md_ctx, kSignature, sizeof(kSignature))) { goto out; } ret = 1; out: if (!ret) { ERR_print_errors_fp(stderr); } EVP_MD_CTX_free(md_ctx); EVP_PKEY_free(pkey); return ret; }
static int verify_jwt_signature(EVP_PKEY *key, const char *alg, grpc_slice signature, grpc_slice signed_data) { EVP_MD_CTX *md_ctx = EVP_MD_CTX_create(); const EVP_MD *md = evp_md_from_alg(alg); int result = 0; GPR_ASSERT(md != NULL); /* Checked before. */ if (md_ctx == NULL) { gpr_log(GPR_ERROR, "Could not create EVP_MD_CTX."); goto end; } if (EVP_DigestVerifyInit(md_ctx, NULL, md, NULL, key) != 1) { gpr_log(GPR_ERROR, "EVP_DigestVerifyInit failed."); goto end; } if (EVP_DigestVerifyUpdate(md_ctx, GRPC_SLICE_START_PTR(signed_data), GRPC_SLICE_LENGTH(signed_data)) != 1) { gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed."); goto end; } if (EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(signature), GRPC_SLICE_LENGTH(signature)) != 1) { gpr_log(GPR_ERROR, "JWT signature verification failed."); goto end; } result = 1; end: if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); return result; }
static bool verifySignature(const char *data, int dataLength, char *signature, int signatureLength, const char *cert) { X509* x509; BIO* bio = BIO_new(BIO_s_mem()); BIO_puts(bio, cert); x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); BIO_free(bio); if (!x509) { return false; } EVP_PKEY* pubKey = X509_get_pubkey(x509); EVP_MD_CTX *mdctx = NULL; mdctx = EVP_MD_CTX_create(); EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pubKey); EVP_DigestVerifyUpdate(mdctx, data, dataLength); int result = EVP_DigestVerifyFinal(mdctx, signature, signatureLength); X509_free(x509); EVP_PKEY_free(pubKey); EVP_MD_CTX_destroy(mdctx); return result > 0; }
bool verifySignature(RSA* rsa, unsigned char* rawSignature, size_t rawSignatureLength, const char* rawContent, size_t rawContentLength, bool* authentic) { *authentic = false; EVP_PKEY* pubKey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pubKey, rsa); EVP_MD_CTX* m_RSAVerifyCtx = EVP_MD_CTX_create(); if (EVP_DigestVerifyInit(m_RSAVerifyCtx, NULL, EVP_sha256(), NULL, pubKey) <= 0) { return false; } if (EVP_DigestVerifyUpdate(m_RSAVerifyCtx, rawContent, rawContentLength) <= 0) { return false; } int AuthStatus = EVP_DigestVerifyFinal(m_RSAVerifyCtx, rawSignature, rawSignatureLength); if (AuthStatus == 1) { *authentic = true; EVP_MD_CTX_cleanup(m_RSAVerifyCtx); return true; } else if(AuthStatus == 0){ *authentic = false; EVP_MD_CTX_cleanup(m_RSAVerifyCtx); return true; } else{ *authentic = false; EVP_MD_CTX_cleanup(m_RSAVerifyCtx); return false; } }
bool NvPairingManager::verifySignature(QByteArray data, QByteArray signature, QByteArray serverCertificate) { BIO* bio = BIO_new_mem_buf(serverCertificate.data(), -1); THROW_BAD_ALLOC_IF_NULL(bio); X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); BIO_free_all(bio); EVP_PKEY* pubKey = X509_get_pubkey(cert); THROW_BAD_ALLOC_IF_NULL(pubKey); EVP_MD_CTX* mdctx = EVP_MD_CTX_create(); THROW_BAD_ALLOC_IF_NULL(mdctx); EVP_DigestVerifyInit(mdctx, nullptr, EVP_sha256(), nullptr, pubKey); EVP_DigestVerifyUpdate(mdctx, data.data(), data.length()); int result = EVP_DigestVerifyFinal(mdctx, reinterpret_cast<unsigned char*>(signature.data()), signature.length()); EVP_PKEY_free(pubKey); EVP_MD_CTX_destroy(mdctx); X509_free(cert); return result > 0; }
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) { EVP_MD_CTX ctx; uint8_t *buf_in = NULL; int ret = 0, inl; if (!pkey) { OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { OPENSSL_PUT_ERROR(X509, ASN1_item_verify, X509_R_INVALID_BIT_STRING_BITS_LEFT); return 0; } EVP_MD_CTX_init(&ctx); if (!EVP_DigestVerifyInitFromAlgorithm(&ctx, a, pkey)) { goto err; } inl = ASN1_item_i2d(asn, &buf_in, it); if (buf_in == NULL) { OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl)) { OPENSSL_cleanse(buf_in,(unsigned int)inl); OPENSSL_free(buf_in); OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_EVP_LIB); goto err; } OPENSSL_cleanse(buf_in,(unsigned int)inl); OPENSSL_free(buf_in); if (EVP_DigestVerifyFinal(&ctx,signature->data, (size_t)signature->length) <= 0) { OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_EVP_LIB); 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; }
static int test_EVP_DigestVerifyInitFromAlgorithm(void) { int ret = 0; CBS cert, cert_body, tbs_cert, algorithm, signature; uint8_t padding; X509_ALGOR *algor = NULL; const uint8_t *derp; EVP_PKEY *pkey = NULL; EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert)); if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) || CBS_len(&cert) != 0 || !CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) || !CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) || CBS_len(&cert_body) != 0) { fprintf(stderr, "Failed to parse certificate\n"); goto out; } /* Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the leading phase byte is just a zero. */ if (!CBS_get_u8(&signature, &padding) || padding != 0) { fprintf(stderr, "Invalid signature padding\n"); goto out; } derp = CBS_data(&algorithm); if (!d2i_X509_ALGOR(&algor, &derp, CBS_len(&algorithm)) || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) { fprintf(stderr, "Failed to parse algorithm\n"); } pkey = load_example_rsa_key(); if (pkey == NULL || !EVP_DigestVerifyInitFromAlgorithm(&md_ctx, algor, pkey) || !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&tbs_cert), CBS_len(&tbs_cert)) || !EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature), CBS_len(&signature))) { goto out; } ret = 1; out: if (!ret) { BIO_print_errors_fp(stderr); } EVP_MD_CTX_cleanup(&md_ctx); if (pkey) { EVP_PKEY_free(pkey); } return ret; }
static LUA_FUNCTION(openssl_verifyUpdate) { size_t l; int ret; EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); const char* data = luaL_checklstring(L, 2, &l); ret = EVP_DigestVerifyUpdate(ctx, data, l); return openssl_pushresult(L, ret); }
int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen) { if (ctx->pctx->pmeth->digestverify != NULL) return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen); if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) return -1; return EVP_DigestVerifyFinal(ctx, sigret, siglen); }
static int test_EVP_DigestSignInit(void) { int ret = 0; EVP_PKEY *pkey = NULL; uint8_t *sig = NULL; size_t sig_len = 0; EVP_MD_CTX md_ctx, md_ctx_verify; EVP_MD_CTX_init(&md_ctx); EVP_MD_CTX_init(&md_ctx_verify); pkey = load_example_rsa_key(); if (pkey == NULL || !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) || !EVP_DigestSignUpdate(&md_ctx, kMsg, sizeof(kMsg))) { goto out; } /* Determine the size of the signature. */ if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) { goto out; } /* Sanity check for testing. */ if (sig_len != EVP_PKEY_size(pkey)) { fprintf(stderr, "sig_len mismatch\n"); goto out; } sig = malloc(sig_len); if (sig == NULL || !EVP_DigestSignFinal(&md_ctx, sig, &sig_len)) { goto out; } /* Ensure that the signature round-trips. */ if (!EVP_DigestVerifyInit(&md_ctx_verify, NULL, EVP_sha256(), NULL, pkey) || !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) || !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) { goto out; } ret = 1; out: if (!ret) { BIO_print_errors_fp(stderr); } EVP_MD_CTX_cleanup(&md_ctx); EVP_MD_CTX_cleanup(&md_ctx_verify); if (pkey) { EVP_PKEY_free(pkey); } if (sig) { free(sig); } 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; md_ctx = EVP_MD_CTX_new(); md_ctx_verify = EVP_MD_CTX_new(); if (md_ctx == NULL || md_ctx_verify == NULL) goto out; pkey = load_example_rsa_key(); if (pkey == NULL || !EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) || !EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) { goto out; } /* Determine the size of the signature. */ if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) { goto out; } /* Sanity check for testing. */ if (sig_len != (size_t)EVP_PKEY_size(pkey)) { fprintf(stderr, "sig_len mismatch\n"); goto out; } sig = OPENSSL_malloc(sig_len); if (sig == NULL || !EVP_DigestSignFinal(md_ctx, sig, &sig_len)) { goto out; } /* Ensure that the signature round-trips. */ if (!EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sha256(), NULL, pkey) || !EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg)) || !EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len)) { goto out; } ret = 1; out: if (!ret) { ERR_print_errors_fp(stderr); } EVP_MD_CTX_free(md_ctx); EVP_MD_CTX_free(md_ctx_verify); EVP_PKEY_free(pkey); OPENSSL_free(sig); return ret; }
/* test_algorithm_roundtrip signs a message using an already-initialized * |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the * AlgorithmIdentifier to verify the signature. */ static int test_algorithm_roundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { int ret = 0; uint8_t *sig = NULL; size_t sig_len = 0; EVP_MD_CTX md_ctx_verify; X509_ALGOR *algor = NULL; EVP_MD_CTX_init(&md_ctx_verify); if (!EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) { goto out; } /* Save the algorithm. */ algor = X509_ALGOR_new(); if (algor == NULL || !EVP_DigestSignAlgorithm(md_ctx, algor)) { goto out; } /* Determine the size of the signature. */ if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) { goto out; } /* Sanity check for testing. */ if (sig_len != EVP_PKEY_size(pkey)) { fprintf(stderr, "sig_len mismatch\n"); goto out; } sig = malloc(sig_len); if (sig == NULL || !EVP_DigestSignFinal(md_ctx, sig, &sig_len)) { goto out; } /* Ensure that the signature round-trips. */ if (!EVP_DigestVerifyInitFromAlgorithm(&md_ctx_verify, algor, pkey) || !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) || !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) { goto out; } ret = 1; out: EVP_MD_CTX_cleanup(&md_ctx_verify); if (sig) { free(sig); } if (algor) { X509_ALGOR_free(algor); } return ret; }
static int verify_update(struct swupdate_digest *dgst, char *msg, unsigned int mlen) { int rc; rc = EVP_DigestVerifyUpdate(dgst->ctx, msg, mlen); if(rc != 1) { ERROR("EVP_DigestVerifyUpdate failed, error 0x%lx", ERR_get_error()); return -EFAULT; } return 0; }
//Verify the given data was used to create the given digital signature bool digiVerify(const char *b64Signature, size32_t dataSz, const void *data, const CLoadedKey &verifyingKey) { OwnedEVPMdCtx verifyingCtx(EVP_MD_CTX_create()); int rc = EVP_DigestVerifyInit(verifyingCtx, nullptr, EVP_sha256(), nullptr, verifyingKey); if (rc <= 0) throwEVPException(-1, "digiVerify:EVP_DigestVerifyInit"); //decode base64 signature StringBuffer decodedSig; JBASE64_Decode(b64Signature, decodedSig); if (EVP_DigestVerifyUpdate(verifyingCtx, data, dataSz) <= 0) throwEVPException(-1, "digiVerify:EVP_DigestVerifyUpdate"); return 1 == EVP_DigestVerifyFinal(verifyingCtx, (unsigned char *)decodedSig.str(), decodedSig.length()); }
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; }
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 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; }
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); }
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; }
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); }
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 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; }
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; }
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; }