//Create base 64 encoded digital signature of given data bool digiSign(StringBuffer &b64Signature, size32_t dataSz, const void *data, const CLoadedKey &signingKey) { OwnedEVPMdCtx signingCtx(EVP_MD_CTX_create()); //initialize context for SHA-256 hashing function int rc = EVP_DigestSignInit(signingCtx, nullptr, EVP_sha256(), nullptr, signingKey); if (rc <= 0) throwEVPException(-1, "digiSign:EVP_DigestSignInit"); //add string to the context if (EVP_DigestSignUpdate(signingCtx, data, dataSz) <= 0) throwEVPException(-1, "digiSign:EVP_DigestSignUpdate"); //compute length of signature size_t encMsgLen; if (EVP_DigestSignFinal(signingCtx, nullptr, &encMsgLen) <= 0) throwEVPException(-1, "digiSign:EVP_DigestSignFinal1"); if (encMsgLen == 0) throwEVPException(-1, "digiSign:EVP_DigestSignFinal length returned 0"); //compute signature (signed digest) OwnedEVPMemory encMsg = OPENSSL_malloc(encMsgLen); if (encMsg == nullptr) throw MakeStringException(-1, "digiSign:OPENSSL_malloc(%u) returned NULL", (unsigned)encMsgLen); if (EVP_DigestSignFinal(signingCtx, (unsigned char *)encMsg.get(), &encMsgLen) <= 0) throwEVPException(-1, "digiSign:EVP_DigestSignFinal2"); //convert to base64 JBASE64_Encode(encMsg, encMsgLen, b64Signature, false); return true; }
static int PKCS7_SIGNER_INFO_sign_0(PKCS7_SIGNER_INFO *si) { EVP_MD_CTX mctx; EVP_PKEY_CTX *pctx; unsigned char *abuf = NULL; int alen; size_t siglen; const EVP_MD *md = NULL; md = EVP_get_digestbyobj(si->digest_alg->algorithm); if (md == NULL) return 0; EVP_MD_CTX_init(&mctx); if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) goto err; if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); goto err; } alen = ASN1_item_i2d((ASN1_VALUE *) si->auth_attr, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); if (!abuf) goto err; if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) goto err; OPENSSL_free(abuf); abuf = NULL; if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) goto err; abuf = OPENSSL_malloc(siglen); if (!abuf) goto err; if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) goto err; if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); goto err; } EVP_MD_CTX_cleanup(&mctx); ASN1_STRING_set0(si->enc_digest, abuf, siglen); return 1; err: if (abuf) OPENSSL_free(abuf); EVP_MD_CTX_cleanup(&mctx); return 0; }
Handle<std::string> RSA_PKCS1_sign(Handle<ScopedEVP_PKEY> hKey, const EVP_MD *md, Handle<std::string> hData) { LOG_FUNC(); ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); EVP_PKEY_CTX* pctx = nullptr; size_t siglen = 0; if (ctx.isEmpty() || !EVP_DigestSignInit(ctx.Get(), &pctx, md, nullptr, hKey->Get())) { THROW_OPENSSL("EVP_DigestSignInit"); } byte* data = (byte*)hData->c_str(); size_t datalen = hData->length(); if (1 != EVP_DigestSignUpdate(ctx.Get(), data, datalen)) { THROW_OPENSSL("EVP_DigestSignUpdate"); } if (1 != EVP_DigestSignFinal(ctx.Get(), nullptr, &siglen)) { THROW_OPENSSL("EVP_DigestSignFinal"); } Handle<std::string> hOutput(new std::string()); hOutput->resize(siglen); byte *output = (byte*)hOutput->c_str(); if (!EVP_DigestSignFinal(ctx.Get(), output, &siglen)) THROW_OPENSSL("EVP_DigestSignFinal"); return hOutput; }
int signMsgRSA(EVP_PKEY* key, const unsigned char* msg, unsigned char** sig, size_t* slen, size_t msglen){ EVP_MD_CTX* ctx = NULL; const EVP_MD* md = NULL; if(msg == NULL || sig == NULL || slen == NULL) return 0; 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_DigestSignInit(ctx, NULL, md, NULL, key)){ printf("ERR EVP_DigestSignInit\n"); return 0; } /*SE FIRMA EL MENSAJE*/ if(1 != EVP_DigestSignUpdate(ctx, msg, msglen)){ printf("ERR EVP_DigestSignUpdate\n"); return 0; } if(1 != EVP_DigestSignFinal(ctx, NULL, slen)){ printf("ERR EVP_DigestSignFinal\n"); return 0; } *sig = OPENSSL_malloc(*slen); if(*sig == NULL){ printf("ERR OPENSSL_malloc\n"); } if(1 != EVP_DigestSignFinal(ctx, *sig, slen)){ printf("ERR EVP_DigestSignFinal\n"); return 0; } EVP_MD_CTX_destroy(ctx); ctx = NULL; return 1; }
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 sign_it(const unsigned char *msg, size_t mlen, unsigned char **sig, size_t *slen, EVP_PKEY *pkey) { int result = GS_FAILED; *sig = NULL; *slen = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_create(); if (ctx == NULL) return GS_FAILED; const EVP_MD *md = EVP_get_digestbyname("SHA256"); if (md == NULL) goto cleanup; int rc = EVP_DigestInit_ex(ctx, md, NULL); if (rc != 1) goto cleanup; rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey); if (rc != 1) goto cleanup; rc = EVP_DigestSignUpdate(ctx, msg, mlen); if (rc != 1) goto cleanup; size_t req = 0; rc = EVP_DigestSignFinal(ctx, NULL, &req); if (rc != 1 || !(req > 0)) goto cleanup; *sig = OPENSSL_malloc(req); if (*sig == NULL) goto cleanup; *slen = req; rc = EVP_DigestSignFinal(ctx, *sig, slen); if (rc != 1 || req != *slen) goto cleanup; result = GS_OK; cleanup: EVP_MD_CTX_destroy(ctx); ctx = NULL; return result; }
static int sign(void *ctx,char *file,void *in,int ilen,void *out,int *olen) { int r=NOCARD; size_t slen=*olen; ENGINE *e=(ENGINE *)ctx; EVP_PKEY *key; EVP_MD_CTX *mdc; resume_engine(e,engbits); if(!(key=ENGINE_load_private_key(e,file,NULL,NULL)))goto err1; r=CRYPTOFAIL; if(!(mdc=EVP_MD_CTX_create()))goto err2; if(EVP_DigestInit_ex(mdc,EVP_sha256(),NULL)!=1)goto err3; if(EVP_DigestSignInit(mdc,NULL,EVP_sha256(),NULL,key)!=1)goto err3; if(EVP_DigestSignUpdate(mdc,in,ilen)!=1)goto err3; if(EVP_DigestSignFinal(mdc,out,&slen)!=1)goto err3; *olen=slen; r=OK; err3: EVP_MD_CTX_destroy(mdc); err2: EVP_PKEY_free(key); err1: suspend_engine(e,&engbits); return r; }
/* * Generates the mac for the Finished message. Returns the length of the MAC or * 0 on error. */ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, unsigned char *out) { const EVP_MD *md = ssl_handshake_md(s); unsigned char hash[EVP_MAX_MD_SIZE]; size_t hashlen, ret = 0; EVP_PKEY *key = NULL; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) goto err; if (str == s->method->ssl3_enc->server_finished_label) key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, s->server_finished_secret, hashlen); else key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, s->client_finished_secret, hashlen); if (key == NULL || ctx == NULL || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0 || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0 || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) goto err; ret = hashlen; err: EVP_PKEY_free(key); EVP_MD_CTX_free(ctx); return ret; }
void SignerFilter::finalize() { size_t sigLen = 0; if (EVP_DigestSignFinal(m_impl->ctx, nullptr, &sigLen) != 1) NDN_THROW(Error(getIndex(), "Failed to estimate buffer length")); auto buffer = make_unique<OBuffer>(sigLen); if (EVP_DigestSignFinal(m_impl->ctx, buffer->data(), &sigLen) != 1) NDN_THROW(Error(getIndex(), "Failed to finalize signature")); buffer->erase(buffer->begin() + sigLen, buffer->end()); setOutputBuffer(std::move(buffer)); flushAllOutput(); }
static int ssl_sign_ecdsa(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, int curve, const EVP_MD *md, const uint8_t *in, size_t in_len) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey); 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 ctx; EVP_MD_CTX_init(&ctx); *out_len = max_out; int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) && EVP_DigestSignUpdate(&ctx, in, in_len) && EVP_DigestSignFinal(&ctx, out, out_len); EVP_MD_CTX_cleanup(&ctx); return ret; }
static int s2n_evp_hmac_p_hash_digest(struct s2n_prf_working_space *ws, void *digest, uint32_t size) { /* EVP_DigestSign API's require size_t data structures */ size_t digest_size = size; GUARD_OSSL(EVP_DigestSignFinal(ws->tls.p_hash.evp_hmac.evp_digest.ctx, (unsigned char *)digest, &digest_size), S2N_ERR_P_HASH_FINAL_FAILED); return 0; }
int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen) { if (ctx->pctx->pmeth->digestsign != NULL) return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen); if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) return 0; return EVP_DigestSignFinal(ctx, sigret, siglen); }
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; }
char *compute_and_encode_signature(const grpc_auth_json_key *json_key, const char *signature_algorithm, const char *to_sign) { const EVP_MD *md = openssl_digest_from_algorithm(signature_algorithm); EVP_MD_CTX *md_ctx = NULL; EVP_PKEY *key = EVP_PKEY_new(); size_t sig_len = 0; unsigned char *sig = NULL; char *result = NULL; if (md == NULL) return NULL; md_ctx = EVP_MD_CTX_create(); if (md_ctx == NULL) { gpr_log(GPR_ERROR, "Could not create MD_CTX"); goto end; } EVP_PKEY_set1_RSA(key, json_key->private_key); if (EVP_DigestSignInit(md_ctx, NULL, md, NULL, key) != 1) { gpr_log(GPR_ERROR, "DigestInit failed."); goto end; } if (EVP_DigestSignUpdate(md_ctx, to_sign, strlen(to_sign)) != 1) { gpr_log(GPR_ERROR, "DigestUpdate failed."); goto end; } if (EVP_DigestSignFinal(md_ctx, NULL, &sig_len) != 1) { gpr_log(GPR_ERROR, "DigestFinal (get signature length) failed."); goto end; } sig = gpr_malloc(sig_len); if (EVP_DigestSignFinal(md_ctx, sig, &sig_len) != 1) { gpr_log(GPR_ERROR, "DigestFinal (signature compute) failed."); goto end; } result = grpc_base64_encode(sig, sig_len, 1, 0); end: if (key != NULL) EVP_PKEY_free(key); if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); if (sig != NULL) gpr_free(sig); return result; }
static bool sig_done(jose_io_t *io) { io_t *i = containerof(io, io_t, io); size_t len = 0; if (EVP_DigestSignFinal(i->emc, NULL, &len) <= 0) return false; uint8_t buf[len]; if (EVP_DigestSignFinal(i->emc, buf, &len) <= 0) return false; if (json_object_set_new(i->sig, "signature", jose_b64_enc(buf, len)) < 0) return false; return add_entity(i->obj, i->sig, "signatures", "signature", "protected", "header", NULL); }
int lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result) { size_t size = lws_genhmac_size(ctx->type); int n = EVP_DigestSignFinal(ctx->ctx, result, &size); EVP_MD_CTX_destroy(ctx->ctx); if (n != 1) return -1; return 0; }
static int ssl_sign_rsa_pkcs1(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md, const uint8_t *in, size_t in_len) { EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); *out_len = max_out; int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) && EVP_DigestSignUpdate(&ctx, in, in_len) && EVP_DigestSignFinal(&ctx, out, out_len); EVP_MD_CTX_cleanup(&ctx); return ret; }
QByteArray NvPairingManager::signMessage(QByteArray message) { EVP_MD_CTX *ctx = EVP_MD_CTX_create(); THROW_BAD_ALLOC_IF_NULL(ctx); const EVP_MD *md = EVP_get_digestbyname("SHA256"); THROW_BAD_ALLOC_IF_NULL(md); EVP_DigestInit_ex(ctx, md, NULL); EVP_DigestSignInit(ctx, NULL, md, NULL, m_PrivateKey); EVP_DigestSignUpdate(ctx, reinterpret_cast<unsigned char*>(message.data()), message.length()); size_t signatureLength = 0; EVP_DigestSignFinal(ctx, NULL, &signatureLength); QByteArray signature((int)signatureLength, 0); EVP_DigestSignFinal(ctx, reinterpret_cast<unsigned char*>(signature.data()), &signatureLength); EVP_MD_CTX_destroy(ctx); return signature; }
/* * Generates the mac for the Finished message. Returns the length of the MAC or * 0 on error. */ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, unsigned char *out) { const EVP_MD *md = ssl_handshake_md(s); unsigned char hash[EVP_MAX_MD_SIZE]; size_t hashlen, ret = 0; EVP_PKEY *key = NULL; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) { /* SSLfatal() already called */ goto err; } if (str == s->method->ssl3_enc->server_finished_label) { key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, s->server_finished_secret, hashlen); } else if (SSL_IS_FIRST_HANDSHAKE(s)) { key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, s->client_finished_secret, hashlen); } else { unsigned char finsecret[EVP_MAX_MD_SIZE]; if (!tls13_derive_finishedkey(s, ssl_handshake_md(s), s->client_app_traffic_secret, finsecret, hashlen)) goto err; key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finsecret, hashlen); OPENSSL_cleanse(finsecret, sizeof(finsecret)); } if (key == NULL || ctx == NULL || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0 || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0 || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); goto err; } ret = hashlen; err: EVP_PKEY_free(key); EVP_MD_CTX_free(ctx); return ret; }
soter_status_t soter_sign_final_rsa_pss_pkcs8(soter_sign_ctx_t* ctx, void* signature, size_t* signature_length) { EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx); if (!pkey) { return SOTER_INVALID_PARAMETER; } if ((*signature_length) < (size_t)EVP_PKEY_size(pkey)) { (*signature_length) = (size_t)EVP_PKEY_size(pkey); return SOTER_BUFFER_TOO_SMALL; } if (!EVP_DigestSignFinal(ctx->md_ctx, signature, signature_length)) { return SOTER_FAIL; } return SOTER_SUCCESS; }
static int ssl_sign_rsa_pss(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md, const uint8_t *in, size_t in_len) { EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); *out_len = max_out; EVP_PKEY_CTX *pctx; int ret = EVP_DigestSignInit(&ctx, &pctx, md, NULL, ssl->cert->privatekey) && 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_DigestSignUpdate(&ctx, in, in_len) && EVP_DigestSignFinal(&ctx, out, out_len); EVP_MD_CTX_cleanup(&ctx); return ret; }
soter_status_t soter_sign_final_ecdsa_none_pkcs8(soter_sign_ctx_t* ctx, void* signature, size_t *signature_length) { EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx); if (!pkey && EVP_PKEY_base_id(pkey)!=EVP_PKEY_EC){ return SOTER_INVALID_PARAMETER; } /* TODO: need review */ soter_status_t res = SOTER_SUCCESS; if(!signature || (*signature_length)<(size_t)EVP_PKEY_size(pkey)){ (*signature_length)=(size_t)EVP_PKEY_size(pkey); res = SOTER_BUFFER_TOO_SMALL; } else { if(EVP_DigestSignFinal(ctx->md_ctx, signature, signature_length)!=1) res = SOTER_INVALID_SIGNATURE; } return res; }
static LUA_FUNCTION(openssl_signFinal) { EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); EVP_PKEY *pkey = lua_gettop(L) > 1 ? CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey") : NULL; size_t siglen = EVP_PKEY_size(pkey); unsigned char *sigbuf = malloc(siglen + 1); int ret = 0; if (pkey) ret = EVP_SignFinal(ctx, sigbuf, (unsigned int *)&siglen, pkey); else ret = EVP_DigestSignFinal(ctx, sigbuf, &siglen); if (ret == 1) { lua_pushlstring(L, (char *)sigbuf, siglen); } free(sigbuf); EVP_MD_CTX_cleanup(ctx); if (ret == 1) return 1; return openssl_pushresult(L, ret); }
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file, BIO *bmd) { size_t len; int i; for (;;) { i = BIO_read(bp, (char *)buf, BUFSIZE); if (i < 0) { BIO_printf(bio_err, "Read Error in %s\n", file); ERR_print_errors(bio_err); return 1; } if (i == 0) break; } if (sigin) { EVP_MD_CTX *ctx; BIO_get_md_ctx(bp, &ctx); i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); if (i > 0) BIO_printf(out, "Verified OK\n"); else if (i == 0) { BIO_printf(out, "Verification Failure\n"); return 1; } else { BIO_printf(bio_err, "Error Verifying Data\n"); ERR_print_errors(bio_err); return 1; } return 0; } if (key) { EVP_MD_CTX *ctx; BIO_get_md_ctx(bp, &ctx); len = BUFSIZE; if (!EVP_DigestSignFinal(ctx, buf, &len)) { BIO_printf(bio_err, "Error Signing Data\n"); ERR_print_errors(bio_err); return 1; } } else { len = BIO_gets(bp, (char *)buf, BUFSIZE); if ((int)len < 0) { ERR_print_errors(bio_err); return 1; } } if (binout) BIO_write(out, buf, len); else if (sep == 2) { for (i = 0; i < (int)len; i++) BIO_printf(out, "%02x", buf[i]); BIO_printf(out, " *%s\n", file); } else { if (sig_name) { BIO_puts(out, sig_name); if (md_name) BIO_printf(out, "-%s", md_name); BIO_printf(out, "(%s)= ", file); } else if (md_name) BIO_printf(out, "%s(%s)= ", md_name, file); else BIO_printf(out, "(%s)= ", file); for (i = 0; i < (int)len; i++) { if (sep && (i != 0)) BIO_printf(out, ":"); BIO_printf(out, "%02x", buf[i]); } BIO_printf(out, "\n"); } return 0; }
int tls1_mac(SSL *ssl, unsigned char *md, int send) { SSL3_RECORD *rec; unsigned char *seq; EVP_MD_CTX *hash; size_t md_size; int i; EVP_MD_CTX hmac, *mac_ctx; unsigned char buf[5]; int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM)); int t; if (send) { rec= &(ssl->s3->wrec); seq= &(ssl->s3->write_sequence[0]); hash=ssl->write_hash; } else { rec= &(ssl->s3->rrec); seq= &(ssl->s3->read_sequence[0]); hash=ssl->read_hash; } t=EVP_MD_CTX_size(hash); TINYCLR_SSL_ASSERT(t >= 0); md_size=t; buf[0]=rec->type; buf[1]=(unsigned char)(ssl->version>>8); buf[2]=(unsigned char)(ssl->version); buf[3]=rec->length>>8; buf[4]=rec->length&0xff; /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ if (stream_mac) { mac_ctx = hash; } else { EVP_MD_CTX_copy(&hmac,hash); mac_ctx = &hmac; } if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER) { unsigned char dtlsseq[8],*p=dtlsseq; s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); TINYCLR_SSL_MEMCPY (p,&seq[2],6); EVP_DigestSignUpdate(mac_ctx,dtlsseq,8); } else EVP_DigestSignUpdate(mac_ctx,seq,8); EVP_DigestSignUpdate(mac_ctx,buf,5); EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); t=EVP_DigestSignFinal(mac_ctx,md,&md_size); TINYCLR_SSL_ASSERT(t > 0); if (!stream_mac) EVP_MD_CTX_cleanup(&hmac); #ifdef TLS_DEBUG TINYCLR_SSL_PRINTF("sec="); {unsigned int z; for (z=0; z<md_size; z++) TINYCLR_SSL_PRINTF("%02X ",mac_sec[z]); TINYCLR_SSL_PRINTF("\n"); } TINYCLR_SSL_PRINTF("seq="); {int z; for (z=0; z<8; z++) TINYCLR_SSL_PRINTF("%02X ",seq[z]); TINYCLR_SSL_PRINTF("\n"); } TINYCLR_SSL_PRINTF("buf="); {int z; for (z=0; z<5; z++) TINYCLR_SSL_PRINTF("%02X ",buf[z]); TINYCLR_SSL_PRINTF("\n"); } TINYCLR_SSL_PRINTF("rec="); {unsigned int z; for (z=0; z<rec->length; z++) TINYCLR_SSL_PRINTF("%02X ",buf[z]); TINYCLR_SSL_PRINTF("\n"); } #endif if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER) { for (i=7; i>=0; i--) { ++seq[i]; if (seq[i] != 0) break; } } #ifdef TLS_DEBUG {unsigned int z; for (z=0; z<md_size; z++) TINYCLR_SSL_PRINTF("%02X ",md[z]); TINYCLR_SSL_PRINTF("\n"); } #endif return(md_size); }
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; }
int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) { const EVP_MD *type; EVP_PKEY *pkey; unsigned char *buf_in = NULL, *buf_out = NULL; size_t inl = 0, outl = 0, outll = 0; int signid, paramtype; int rv; type = EVP_MD_CTX_md(ctx); pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (!type || !pkey) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } if (pkey->ameth->item_sign) { rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); if (rv == 1) outl = signature->length; /*- * Return value meanings: * <=0: error. * 1: method does everything. * 2: carry on as normal. * 3: ASN1 method sets algorithm identifiers: just sign. */ if (rv <= 0) ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); if (rv <= 1) goto err; } else rv = 2; if (rv == 2) { if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { if (!pkey->ameth || !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey->ameth->pkey_id)) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } } else signid = type->pkey_type; if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) paramtype = V_ASN1_NULL; else paramtype = V_ASN1_UNDEF; if (algor1) X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); if (algor2) X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); } inl = ASN1_item_i2d(asn, &buf_in, it); outll = outl = EVP_PKEY_size(pkey); buf_out = OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestSignUpdate(ctx, buf_in, inl) || !EVP_DigestSignFinal(ctx, buf_out, &outl)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); goto err; } if (signature->data != NULL) OPENSSL_free(signature->data); signature->data = buf_out; buf_out = NULL; signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; err: EVP_MD_CTX_cleanup(ctx); if (buf_in != NULL) { OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) { OPENSSL_cleanse((char *)buf_out, outll); OPENSSL_free(buf_out); } return (outl); }
static char *ngx_http_acme_sign_json(ngx_conf_t *cf, void *conf, json_t *payload, RSA *key, ngx_str_t replay_nonce, json_t **flattened_jws) { /* * Structure according to RFC7515: * * { * "payload":"<payload contents>", * "protected":"<integrity-protected header contents>", * "header":<non-integrity-protected header contents>, * "signature":"<signature contents>" * } * * Example: * * { * "payload": * "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ", * "protected":"eyJhbGciOiJFUzI1NiJ9", * "header": {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"}, * "signature": * "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q" * } */ /* * ACME restrictions: * The JWS MUST use the Flattened JSON Serialization * The JWS MUST be encoded using UTF-8 * The JWS Header or Protected Header MUST include “alg” and “jwk” fields * The JWS MUST NOT have the value “none” in its “alg” field */ json_t *jwk; json_t *header; ngx_str_t encoded_protected_header, serialized_payload, encoded_payload, tmp; ngx_str_t signing_input, signature, encoded_signature; u_char *tmp_char_p; /* Variables for signing */ EVP_PKEY *evp_key; EVP_MD_CTX *mdctx = NULL; int ret = 0; /* * Encode payload */ serialized_payload = (ngx_str_t)ngx_string_dynamic(json_dumps(payload, 0)); encoded_payload.len = ngx_base64_encoded_length(serialized_payload.len); encoded_payload.data = ngx_alloc(encoded_payload.len, cf->log); ngx_encode_base64url(&encoded_payload, &serialized_payload); println_debug("Signing payload: ", &serialized_payload); /* * Create header */ /* jwk header */ if(ngx_http_acme_create_jwk(cf, conf, key, &jwk) != NGX_CONF_OK) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Failed to create the JWK from the account key"); ngx_free(serialized_payload.data); ngx_free(encoded_payload.data); return NGX_CONF_ERROR; } /* Pack header into JSON */ header = json_pack("{s:s, s:s%, s:o}", "alg", "RS256", "nonce", replay_nonce.data, replay_nonce.len, "jwk", jwk); if(header == NULL) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error packing JWS header"); ngx_free(serialized_payload.data); ngx_free(encoded_payload.data); return NGX_CONF_ERROR; } /* Serialize and base64url encode header */ tmp = (ngx_str_t)ngx_string_dynamic(json_dumps(header, 0)); encoded_protected_header.len = ngx_base64_encoded_length(tmp.len); encoded_protected_header.data = ngx_alloc(encoded_protected_header.len, cf->log); ngx_encode_base64url(&encoded_protected_header, &tmp); ngx_free(tmp.data); json_decref(header); /* * Create signature */ /* Create signing input */ /* = ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload)) */ signing_input.len = encoded_protected_header.len + strlen(".") + encoded_payload.len; signing_input.data = ngx_alloc(signing_input.len, cf->log); tmp_char_p = ngx_copy(signing_input.data, encoded_protected_header.data, encoded_protected_header.len); tmp_char_p = ngx_copy(tmp_char_p, ".", strlen(".")); tmp_char_p = ngx_copy(tmp_char_p, encoded_payload.data, encoded_payload.len); /* Convert the RSA key to the EVP_PKEY structure */ evp_key = EVP_PKEY_new(); if(evp_key == NULL) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error signing the message digest for the JWS signature."); return NGX_CONF_ERROR; } if(EVP_PKEY_set1_RSA(evp_key, key) == 0) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error signing the message digest for the JWS signature."); return NGX_CONF_ERROR; } /* Create the message digest context */ ret = 0; mdctx = EVP_MD_CTX_create(); if(mdctx == NULL) goto err; /* Initialize the DigestSign operation - SHA-256 has been selected as the message digest function */ if(EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, evp_key) != 1) goto err; /* Call update with the message */ if(EVP_DigestSignUpdate(mdctx, signing_input.data, signing_input.len) != 1) goto err; /* Finalise the DigestSign operation */ /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the */ /* signature. The length is returned in siglen. */ if(EVP_DigestSignFinal(mdctx, NULL, &signature.len) != 1) goto err; /* Allocate memory for the signature */ signature.data = ngx_alloc(signature.len, cf->log); /* Obtain the signature */ if(EVP_DigestSignFinal(mdctx, signature.data, &signature.len) != 1) goto err; /* Success */ ret = 1; err: if(ret != 1) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error signing the message digest for the JWS signature. OpenSSL error 0x%xl", ERR_get_error()); return NGX_CONF_ERROR; } /* Clean up */ EVP_MD_CTX_destroy(mdctx); EVP_PKEY_free(evp_key); /* base64url encode the signature */ encoded_signature.len = ngx_base64_encoded_length(signature.len); encoded_signature.data = ngx_alloc(encoded_signature.len, cf->log); ngx_encode_base64url(&encoded_signature, &signature); ngx_free(signature.data); /* * Create flattened JWS serialization */ *flattened_jws = json_pack("{s:s%,s:s%,s:s%}", "payload", encoded_payload.data, encoded_payload.len, "protected", encoded_protected_header.data, encoded_protected_header.len, "signature", encoded_signature.data, encoded_signature.len ); ngx_free(serialized_payload.data); // TODO (KK) Maybe this is too early for a free since the strings will be used in the flattened JWS (but when to free then?) ngx_free(encoded_payload.data); ngx_free(encoded_protected_header.data); ngx_free(encoded_signature.data); if(*flattened_jws == NULL) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error serializing flattened JWS"); return NGX_CONF_ERROR; } return NGX_CONF_OK; } /* ngx_http_acme_sign_json */