static isc_result_t opensslgost_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; isc_region_t r; unsigned int siglen = 0; EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; isc_buffer_availableregion(sig, &r); if (r.length < (unsigned int) EVP_PKEY_size(pkey)) return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) return (ISC_R_FAILURE); isc_buffer_add(sig, siglen); return (ISC_R_SUCCESS); }
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); }
/** @fn size_t soap_smd_size(int alg, const void *key) @brief Returns the number of octets needed to store the digest or signature returned by soap_smd_end. @param[in] alg is the digest or signature algorithm to be used @param[in] key is a pointer to an EVP_PKEY object for RSA/DSA signatures or NULL for digests and HMAC @return size_t number of octets that is needed to hold digest or signature @see soap_smd_end The values returned for digests are SOAP_SMD_MD5_SIZE and SOAP_SMD_SHA1_SIZE. */ size_t soap_smd_size(int alg, const void *key) { switch (alg & (SOAP_SMD_PASSTHRU-1)) { case SOAP_SMD_DGST_MD5: return SOAP_SMD_MD5_SIZE; case SOAP_SMD_DGST_SHA1: case SOAP_SMD_HMAC_SHA1: return SOAP_SMD_SHA1_SIZE; case SOAP_SMD_DGST_SHA256: return SOAP_SMD_SHA256_SIZE; case SOAP_SMD_SIGN_DSA_SHA1: case SOAP_SMD_SIGN_RSA_SHA1: case SOAP_SMD_SIGN_RSA_SHA256: case SOAP_SMD_VRFY_DSA_SHA1: case SOAP_SMD_VRFY_RSA_SHA1: /* OpenSSL EVP_PKEY_size returns size of signatures given a key */ return EVP_PKEY_size((EVP_PKEY*)key); } return 0; }
void genAlgorithmProperties(X509* cert, std::string& key, std::string& sig, std::string& size) { int nid = 0; nid = OBJ_obj2nid(cert->cert_info->key->algor->algorithm); if (nid != NID_undef) { key = std::string(OBJ_nid2ln(nid)); // Get EVP public key, to determine public key size. EVP_PKEY* pkey = nullptr; pkey = X509_get_pubkey(cert); if (pkey != nullptr) { if (nid == NID_rsaEncryption || nid == NID_dsa) { size_t key_size = 0; key_size = EVP_PKEY_size(pkey); size = std::to_string(key_size * 8); } // The EVP_size for EC keys returns the maximum buffer for storing the // key data, it does not indicate the size/strength of the curve. if (nid == NID_X9_62_id_ecPublicKey) { const EC_KEY* ec_pkey = pkey->pkey.ec; const EC_GROUP* ec_pkey_group = nullptr; ec_pkey_group = EC_KEY_get0_group(ec_pkey); int curve_nid = 0; curve_nid = EC_GROUP_get_curve_name(ec_pkey_group); if (curve_nid != NID_undef) { size = std::string(OBJ_nid2ln(curve_nid)); } } } EVP_PKEY_free(pkey); } nid = OBJ_obj2nid(cert->cert_info->signature->algorithm); if (nid != NID_undef) { sig = std::string(OBJ_nid2ln(nid)); } }
bool OSSLGOST::signFinal(ByteString& signature) { // Save necessary state before calling super class signFinal OSSLGOSTPrivateKey* pk = (OSSLGOSTPrivateKey*) currentPrivateKey; if (!AsymmetricAlgorithm::signFinal(signature)) { return false; } // Perform the signature operation EVP_PKEY* pkey = pk->getOSSLKey(); unsigned int outLen; if (pkey == NULL) { ERROR_MSG("Could not get the OpenSSL private key"); EVP_MD_CTX_cleanup(&curCTX); return false; } signature.resize(EVP_PKEY_size(pkey)); outLen = signature.size(); if (!EVP_SignFinal(&curCTX, &signature[0], &outLen, pkey)) { ERROR_MSG("EVP_SignFinal failed"); EVP_MD_CTX_cleanup(&curCTX); return false; } signature.resize(outLen); EVP_MD_CTX_cleanup(&curCTX); return true; }
/* This function signs the buffer passed as argument, returns the length of the signature * else -1 on error * It leaves the sign in **sign_buf (which is allocated) */ int sign_hello(unsigned char* hello_buf,unsigned int hello_len,unsigned char** sign_buf){ EVP_MD_CTX* ctx = NULL; unsigned int sign_len; EVP_PKEY* evp = EVP_PKEY_new(); FILE* fp; *sign_buf = NULL; ctx = (EVP_MD_CTX*)calloc(1,sizeof(EVP_MD_CTX)); EVP_MD_CTX_init(ctx); OpenSSL_add_all_algorithms(); if((fp=fopen(PRIV_KEY,"r"))==NULL){ goto fail; } if((evp=PEM_read_PrivateKey(fp,NULL,NULL,NULL))==NULL){ goto fail; } *sign_buf = (unsigned char*)calloc(1,EVP_PKEY_size(evp)); if(EVP_SignInit(ctx,EVP_sha512())==0){ goto fail; } if(EVP_SignUpdate(ctx,hello_buf,hello_len)==0){ goto fail; } if(EVP_SignFinal(ctx,*sign_buf,&sign_len,evp)==0){ goto fail; } EVP_MD_CTX_cleanup(ctx); free(ctx); EVP_PKEY_free(evp); return sign_len; fail: EVP_MD_CTX_cleanup(ctx); free(ctx); if (*sign_buf != NULL) { free(*sign_buf); } return -1; }
static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!out) { *outlen = key_len; return 1; } if (*outlen < key_len) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_decrypt, EVP_R_BUFFER_TOO_SMALL); return 0; } if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { size_t plaintext_len; int message_len; if (!setup_tbuf(rctx, ctx) || !RSA_decrypt(rsa, &plaintext_len, rctx->tbuf, key_len, in, inlen, RSA_NO_PADDING)) { return 0; } message_len = RSA_padding_check_PKCS1_OAEP_mgf1( out, key_len, rctx->tbuf, plaintext_len, rctx->oaep_label, rctx->oaep_labellen, rctx->md, rctx->mgf1md); if (message_len < 0) { return 0; } *outlen = message_len; return 1; } return RSA_decrypt(rsa, outlen, out, key_len, in, inlen, rctx->pad_mode); }
static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { const EVP_MD *sigmd, *mgf1md; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen; if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) return NULL; if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) return NULL; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) return NULL; if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if ((EVP_PKEY_bits(pk) & 0x7) == 1) saltlen--; } return rsa_pss_params_create(sigmd, mgf1md, saltlen); }
static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; size_t rslen; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (rctx->md) { switch (rctx->pad_mode) { case RSA_PKCS1_PADDING: return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); case RSA_PKCS1_PSS_PADDING: if (!setup_tbuf(rctx, ctx) || !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, RSA_NO_PADDING) || !RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md, rctx->mgf1md, rctx->tbuf, rctx->saltlen)) { return 0; } return 1; default: return 0; } } if (!setup_tbuf(rctx, ctx) || !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, rctx->pad_mode) || rslen != tbslen || CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) { return 0; } return 1; }
/* * call-seq: * pkey.sign(digest, data) -> String * * To sign the +String+ +data+, +digest+, an instance of OpenSSL::Digest, must * be provided. The return value is again a +String+ containing the signature. * A PKeyError is raised should errors occur. * Any previous state of the +Digest+ instance is irrelevant to the signature * outcome, the digest instance is reset to its initial state during the * operation. * * == Example * data = 'Sign me!' * digest = OpenSSL::Digest::SHA256.new * pkey = OpenSSL::PKey::RSA.new(2048) * signature = pkey.sign(digest, data) */ static VALUE ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) { EVP_PKEY *pkey; EVP_MD_CTX ctx; unsigned int buf_len; VALUE str; if (rb_funcallv(self, id_private_q, 0, NULL) != Qtrue) { ossl_raise(rb_eArgError, "Private key is needed."); } GetPKey(self, pkey); EVP_SignInit(&ctx, GetDigestPtr(digest)); StringValue(data); EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data)); str = rb_str_new(0, EVP_PKEY_size(pkey)+16); if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey)) ossl_raise(ePKeyError, NULL); assert((long)buf_len <= RSTRING_LEN(str)); rb_str_set_len(str, buf_len); return str; }
/** Low-level signature operation. * \param key_count Number of keys in the \a source array. * \param source Array of keys. The keys must include private key data. * \param data Data to sign. * \return Array of signatures, one for each key, * or NULL if the operation failed. * \sa gale_crypto_verify_raw(), gale_crypto_sign() */ const struct gale_data *gale_crypto_sign_raw(int key_count, const struct gale_group *source, struct gale_data data) { int i; struct gale_data *output; RSA *rsa; EVP_MD_CTX *context = EVP_MD_CTX_new(); EVP_SignInit(context,EVP_md5()); EVP_SignUpdate(context,data.p,data.l); gale_create_array(output,key_count); for (i = 0; NULL != output && i < key_count; ++i) { EVP_PKEY *key = EVP_PKEY_new(); EVP_PKEY_assign_RSA(key,RSA_new()); rsa = EVP_PKEY_get0_RSA(key); crypto_i_rsa(source[i],rsa); if (!crypto_i_private_valid(rsa)) { gale_alert(GALE_WARNING,G_("invalid private key"),0); output = NULL; goto cleanup; } output[i].p = gale_malloc(EVP_PKEY_size(key)); if (!EVP_SignFinal(context,output[i].p,&output[i].l,key)) { crypto_i_error(); output = NULL; goto cleanup; } cleanup: EVP_PKEY_free(key); } return output; }
int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey) { unsigned char *m; int i,ret=0; unsigned int m_len; m=(unsigned char *)OPENSSL_malloc(EVP_PKEY_size(pkey)+2); if (m == NULL) { PEMerr(PEM_F_PEM_SIGNFINAL,ERR_R_MALLOC_FAILURE); goto err; } if (EVP_SignFinal(ctx,m,&m_len,pkey) <= 0) goto err; i=EVP_EncodeBlock(sigret,m,m_len); *siglen=i; ret=1; err: /* ctx has been zeroed by EVP_SignFinal() */ if (m != NULL) OPENSSL_free(m); return(ret); }
static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo) { int rc, ret; EVP_PKEY_CTX *pkey_ctx = NULL; struct pgpDigSigRSA_s *sig = pgpsig->data; void *padded_sig = NULL; struct pgpDigKeyRSA_s *key = pgpkey->data; if (!constructRSASigningKey(key)) { rc = 1; goto done; } pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL); if (!pkey_ctx) { rc = 1; goto done; } ret = EVP_PKEY_verify_init(pkey_ctx); if (ret < 0) { rc = 1; goto done; } ret = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PADDING); if (ret < 0) { rc = 1; goto done; } ret = EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo)); if (ret < 0) { rc = 1; goto done; } int pkey_len = EVP_PKEY_size(key->evp_pkey); padded_sig = xcalloc(1, pkey_len); if (!BN_bn2binpad(sig->bn, padded_sig, pkey_len)) { rc = 1; goto done; } ret = EVP_PKEY_verify(pkey_ctx, padded_sig, pkey_len, hash, hashlen); if (ret == 1) { /* Success */ rc = 0; } else { /* Failure */ rc = 1; } done: EVP_PKEY_CTX_free(pkey_ctx); free(padded_sig); return rc; }
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) { int ret=0; int i,j; BIO *btmp; BUF_MEM *buf_mem=NULL; BUF_MEM *buf=NULL; PKCS7_SIGNER_INFO *si; EVP_MD_CTX *mdc,ctx_tmp; STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; ASN1_OCTET_STRING *os=NULL; EVP_MD_CTX_init(&ctx_tmp); i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signedAndEnveloped: /* XXXXXXXXXXXXXXXX */ si_sk=p7->d.signed_and_enveloped->signer_info; if (!(os=M_ASN1_OCTET_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); goto err; } p7->d.signed_and_enveloped->enc_data->enc_data=os; break; case NID_pkcs7_enveloped: /* XXXXXXXXXXXXXXXX */ if (!(os=M_ASN1_OCTET_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); goto err; } p7->d.enveloped->enc_data->enc_data=os; break; case NID_pkcs7_signed: si_sk=p7->d.sign->signer_info; os=PKCS7_get_octet_string(p7->d.sign->contents); /* If detached data then the content is excluded */ if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); p7->d.sign->contents->d.data = NULL; } break; case NID_pkcs7_digest: os=PKCS7_get_octet_string(p7->d.digest->contents); /* If detached data then the content is excluded */ if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); p7->d.digest->contents->d.data = NULL; } break; } if (si_sk != NULL) { if ((buf=BUF_MEM_new()) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); goto err; } for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); if (si->pkey == NULL) continue; j=OBJ_obj2nid(si->digest_alg->algorithm); btmp=bio; btmp = PKCS7_find_digest(&mdc, btmp, j); if (btmp == NULL) goto err; /* We now have the EVP_MD_CTX, lets do the * signing. */ EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); goto err; } sk=si->auth_attr; /* If there are attributes, we add the digest * attribute and only sign the attributes */ if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; unsigned int md_len, alen; ASN1_OCTET_STRING *digest; ASN1_UTCTIME *sign_time; const EVP_MD *md_tmp; /* Add signing time if not already present */ if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { if (!(sign_time=X509_gmtime_adj(NULL,0))) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, V_ASN1_UTCTIME,sign_time); } /* Add digest */ md_tmp=EVP_MD_CTX_md(&ctx_tmp); EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); if (!(digest=M_ASN1_OCTET_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } if (!M_ASN1_OCTET_STRING_set(digest,md_data, md_len)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, V_ASN1_OCTET_STRING,digest); /* Now sign the attributes */ EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); if(!abuf) goto err; EVP_SignUpdate(&ctx_tmp,abuf,alen); OPENSSL_free(abuf); } #ifndef OPENSSL_NO_DSA if (si->pkey->type == EVP_PKEY_DSA) ctx_tmp.digest=EVP_dss1(); #endif #ifndef OPENSSL_NO_ECDSA if (si->pkey->type == EVP_PKEY_EC) ctx_tmp.digest=EVP_ecdsa(); #endif if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, (unsigned int *)&buf->length,si->pkey)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); goto err; } if (!ASN1_STRING_set(si->enc_digest, (unsigned char *)buf->data,buf->length)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); goto err; } } } else if (i == NID_pkcs7_digest) { unsigned char md_data[EVP_MAX_MD_SIZE]; unsigned int md_len; if (!PKCS7_find_digest(&mdc, bio, OBJ_obj2nid(p7->d.digest->md->algorithm))) goto err; EVP_DigestFinal_ex(mdc,md_data,&md_len); M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); } if (!PKCS7_is_detached(p7)) { btmp=BIO_find_type(bio,BIO_TYPE_MEM); if (btmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); goto err; } BIO_get_mem_ptr(btmp,&buf_mem); /* Mark the BIO read only then we can use its copy of the data * instead of making an extra copy. */ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(btmp, 0); os->data = (unsigned char *)buf_mem->data; os->length = buf_mem->length; #if 0 M_ASN1_OCTET_STRING_set(os, (unsigned char *)buf_mem->data,buf_mem->length); #endif } ret=1; err: EVP_MD_CTX_cleanup(&ctx_tmp); if (buf != NULL) BUF_MEM_free(buf); return(ret); }
/* adds a Identity header field to msg return value: 1: success 0: else */ static int addIdentity(char * dateHF, struct sip_msg * msg) { #define IDENTITY_HDR_S "Identity: \"" #define IDENTITY_HDR_L (sizeof(IDENTITY_HDR_S)-1) EVP_MD_CTX ctx; unsigned int siglen = 0; int b64len = 0; unsigned char * sig = NULL; char digestString[MAX_DIGEST]; str buf; if(!makeDigestString(digestString, dateHF, msg)) { LM_ERR("error making digest string\n"); return 0; } EVP_SignInit(&ctx, EVP_sha1()); EVP_SignUpdate(&ctx, digestString, strlen(digestString)); sig = pkg_malloc(EVP_PKEY_size(privKey_evp)); if(!sig) { EVP_MD_CTX_cleanup(&ctx); LM_ERR("failed allocating memory\n"); return 0; } if(!EVP_SignFinal(&ctx, sig, &siglen, privKey_evp)) { EVP_MD_CTX_cleanup(&ctx); pkg_free(sig); LM_ERR("error calculating signature\n"); return 0; } EVP_MD_CTX_cleanup(&ctx); /* ###Base64-encoding### */ /* annotation: The next few lines are based on example 7-11 of [VIE-02] */ b64len = (((siglen + 2) / 3) * 4) + 1; buf.len = IDENTITY_HDR_L + b64len + 1 + CRLF_LEN; buf.s = pkg_malloc(buf.len); if(!buf.s) { pkg_free(sig); LM_ERR("error allocating memory\n"); return 0; } memcpy( buf.s, IDENTITY_HDR_S, IDENTITY_HDR_L); EVP_EncodeBlock((unsigned char*)(buf.s+IDENTITY_HDR_L), sig, siglen); memcpy( buf.s+IDENTITY_HDR_L+b64len, "\""CRLF, CRLF_LEN+1); pkg_free(sig); if ( id_add_header( msg, buf.s, buf.len )!=0) { pkg_free(buf.s); LM_ERR("failed to add Identity header\n"); return 0; } return 1; }
/* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i,j; BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; unsigned char *tmp=NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body=NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher=NULL; EVP_CIPHER_CTX *evp_ctx=NULL; X509_ALGOR *enc_alg=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: data_body=PKCS7_get_octet_string(p7->d.sign->contents); md_sk=p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; data_body=p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.signed_and_enveloped->enc_data->algorithm; break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; enc_alg=p7->d.enveloped->enc_data->algorithm; data_body=p7->d.enveloped->enc_data->enc_data; evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.enveloped->enc_data->algorithm; break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) { xa=sk_X509_ALGOR_value(md_sk,i); if ((btmp=BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } j=OBJ_obj2nid(xa->algorithm); evp_md=EVP_get_digestbynid(j); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp,evp_md); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } } if (evp_cipher != NULL) { #if 0 unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char *p; int keylen,ivlen; int max; X509_OBJECT ret; #endif int jj; if ((etmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } /* It was encrypted, we need to decrypt the secret key * with the private key */ /* Find the recipientInfo which matches the passed certificate * (if any) */ if (pcert) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (!pkcs7_cmp_ri(ri, pcert)) break; ri=NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } jj=EVP_PKEY_size(pkey); tmp=(unsigned char *)OPENSSL_malloc(jj+10); if (tmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); goto err; } /* If we haven't got a certificate try each ri in turn */ if (pcert == NULL) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_length(ri->enc_key), pkey); if (jj > 0) break; ERR_clear_error(); ri = NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY); goto err; } } else { jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_length(ri->enc_key), pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); goto err; } } evp_ctx=NULL; BIO_get_cipher_ctx(etmp,&evp_ctx); if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) goto err; if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* Some S/MIME clients don't use the same key * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); goto err; } } if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) goto err; OPENSSL_cleanse(tmp,jj); if (out == NULL) out=etmp; else BIO_push(out,etmp); etmp=NULL; } #if 1 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio=in_bio; } else { #if 0 bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read * EOF and encode the last few bytes */ BIO_set_mem_eof_return(bio,0); if (data_body->length > 0) BIO_write(bio,(char *)data_body->data,data_body->length); #else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data,data_body->length); else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } #endif } BIO_push(out,bio); bio=NULL; #endif if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); if (etmp != NULL) BIO_free_all(etmp); if (bio != NULL) BIO_free_all(bio); out=NULL; } if (tmp != NULL) OPENSSL_free(tmp); return(out); }
int X509_certificate_type(X509 *x, EVP_PKEY *pkey) { EVP_PKEY *pk; int ret = 0, i; if (x == NULL) return (0); if (pkey == NULL) pk = X509_get_pubkey(x); else pk = pkey; if (pk == NULL) return (0); switch (pk->type) { case EVP_PKEY_RSA: ret = EVP_PK_RSA|EVP_PKT_SIGN; /* if (!sign only extension) */ ret |= EVP_PKT_ENC; break; case EVP_PKEY_DSA: ret = EVP_PK_DSA|EVP_PKT_SIGN; break; case EVP_PKEY_EC: ret = EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH; break; case EVP_PKEY_DH: ret = EVP_PK_DH|EVP_PKT_EXCH; break; case NID_id_GostR3410_94: case NID_id_GostR3410_2001: ret = EVP_PKT_EXCH|EVP_PKT_SIGN; break; default: break; } i = OBJ_obj2nid(x->sig_alg->algorithm); if (i && OBJ_find_sigid_algs(i, NULL, &i)) { switch (i) { case NID_rsaEncryption: case NID_rsa: ret |= EVP_PKS_RSA; break; case NID_dsa: case NID_dsa_2: ret |= EVP_PKS_DSA; break; case NID_X9_62_id_ecPublicKey: ret |= EVP_PKS_EC; break; default: break; } } if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look for, not bytes */ ret |= EVP_PKT_EXP; if (pkey == NULL) EVP_PKEY_free(pk); return (ret); }
/*! * \brief Get size of the resulting signature. * * \param key DNSSEC key. * * \return Signature size in bytes. */ static size_t any_sign_size(const knot_dnssec_key_t *key) { assert(key); return (size_t)EVP_PKEY_size(key->data->private_key); }
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 PKCS7_dataFinal(PKCS7 *p7, BIO *bio) { int ret = 0; int i, j; BIO *btmp; PKCS7_SIGNER_INFO *si; EVP_MD_CTX *mdc, ctx_tmp; STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; ASN1_OCTET_STRING *os = NULL; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); return 0; } EVP_MD_CTX_init(&ctx_tmp); i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_data: os = p7->d.data; break; case NID_pkcs7_signedAndEnveloped: /* XXXXXXXXXXXXXXXX */ si_sk = p7->d.signed_and_enveloped->signer_info; os = p7->d.signed_and_enveloped->enc_data->enc_data; if (!os) { os = M_ASN1_OCTET_STRING_new(); if (!os) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } p7->d.signed_and_enveloped->enc_data->enc_data = os; } break; case NID_pkcs7_enveloped: /* XXXXXXXXXXXXXXXX */ os = p7->d.enveloped->enc_data->enc_data; if (!os) { os = M_ASN1_OCTET_STRING_new(); if (!os) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } p7->d.enveloped->enc_data->enc_data = os; } break; case NID_pkcs7_signed: si_sk = p7->d.sign->signer_info; os = PKCS7_get_octet_string(p7->d.sign->contents); /* If detached data then the content is excluded */ if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); os = NULL; p7->d.sign->contents->d.data = NULL; } break; case NID_pkcs7_digest: os = PKCS7_get_octet_string(p7->d.digest->contents); /* If detached data then the content is excluded */ if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); os = NULL; p7->d.digest->contents->d.data = NULL; } break; default: PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } if (si_sk != NULL) { for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); if (si->pkey == NULL) continue; j = OBJ_obj2nid(si->digest_alg->algorithm); btmp = bio; btmp = PKCS7_find_digest(&mdc, btmp, j); if (btmp == NULL) goto err; /* * We now have the EVP_MD_CTX, lets do the signing. */ if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) goto err; sk = si->auth_attr; /* * If there are attributes, we add the digest attribute and only * sign the attributes */ if (sk_X509_ATTRIBUTE_num(sk) > 0) { if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) goto err; } else { unsigned char *abuf = NULL; unsigned int abuflen; abuflen = EVP_PKEY_size(si->pkey); abuf = OPENSSL_malloc(abuflen); if (!abuf) goto err; if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); goto err; } ASN1_STRING_set0(si->enc_digest, abuf, abuflen); } } } else if (i == NID_pkcs7_digest) { unsigned char md_data[EVP_MAX_MD_SIZE]; unsigned int md_len; if (!PKCS7_find_digest(&mdc, bio, OBJ_obj2nid(p7->d.digest->md->algorithm))) goto err; if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) goto err; M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); } if (!PKCS7_is_detached(p7)) { /* * NOTE(emilia): I think we only reach os == NULL here because detached * digested data support is broken. */ if (os == NULL) goto err; if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { char *cont; long contlen; btmp = BIO_find_type(bio, BIO_TYPE_MEM); if (btmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); goto err; } contlen = BIO_get_mem_data(btmp, &cont); /* * Mark the BIO read only then we can use its copy of the data * instead of making an extra copy. */ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(btmp, 0); ASN1_STRING_set0(os, (unsigned char *)cont, contlen); } } ret = 1; err: EVP_MD_CTX_cleanup(&ctx_tmp); return (ret); }
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); }
static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) { int pad_mode; EVP_PKEY_CTX *pkctx = ctx->pctx; if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; if (pad_mode == RSA_PKCS1_PADDING) return 2; if (pad_mode == RSA_PKCS1_PSS_PADDING) { const EVP_MD *sigmd, *mgf1md; RSA_PSS_PARAMS *pss = NULL; X509_ALGOR *mgf1alg = NULL; ASN1_STRING *os1 = NULL, *os2 = NULL; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; sigmd = EVP_MD_CTX_md(ctx); if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) goto err; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) goto err; if (saltlen == -1) saltlen = EVP_MD_size(sigmd); else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) saltlen--; } pss = RSA_PSS_PARAMS_new(); if (!pss) goto err; if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength) goto err; if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) goto err; } if (EVP_MD_type(sigmd) != NID_sha1) { pss->hashAlgorithm = X509_ALGOR_new(); if (!pss->hashAlgorithm) goto err; X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); } if (EVP_MD_type(mgf1md) != NID_sha1) { ASN1_STRING *stmp = NULL; /* need to embed algorithm ID inside another */ mgf1alg = X509_ALGOR_new(); X509_ALGOR_set_md(mgf1alg, mgf1md); if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) goto err; pss->maskGenAlgorithm = X509_ALGOR_new(); if (!pss->maskGenAlgorithm) goto err; X509_ALGOR_set0(pss->maskGenAlgorithm, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1)) goto err; if (alg2) { os2 = ASN1_STRING_dup(os1); if (!os2) goto err; X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os2); } X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os1); os1 = os2 = NULL; rv = 3; err: if (mgf1alg) X509_ALGOR_free(mgf1alg); if (pss) RSA_PSS_PARAMS_free(pss); if (os1) ASN1_STRING_free(os1); return rv; } return 2; }
int dtls1_accept(SSL *s) { BUF_MEM *buf; unsigned long l,Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; int listen; RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; listen = s->d1->listen; /* init things to blank */ s->in_handshake++; if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); s->d1->listen = listen; if (s->cert == NULL) { SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET); return(-1); } for (;;) { state=s->state; switch (s->state) { case SSL_ST_RENEGOTIATE: s->new_session=1; /* s->state=SSL_ST_ACCEPT; */ case SSL_ST_BEFORE: case SSL_ST_ACCEPT: case SSL_ST_BEFORE|SSL_ST_ACCEPT: case SSL_ST_OK|SSL_ST_ACCEPT: s->server=1; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); return -1; } s->type=SSL_ST_ACCEPT; if (s->init_buf == NULL) { if ((buf=BUF_MEM_new()) == NULL) { ret= -1; goto end; } if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) { ret= -1; goto end; } s->init_buf=buf; } if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } s->init_num=0; if (s->state != SSL_ST_RENEGOTIATE) { /* Ok, we now need to push on a buffering BIO so that * the output is sent in a way that TCP likes :-) */ if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } ssl3_init_finished_mac(s); s->state=SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else { /* s->state == SSL_ST_RENEGOTIATE, * we will just send a HelloRequest */ s->ctx->stats.sess_accept_renegotiate++; s->state=SSL3_ST_SW_HELLO_REQ_A; } break; case SSL3_ST_SW_HELLO_REQ_A: case SSL3_ST_SW_HELLO_REQ_B: s->shutdown=0; dtls1_start_timer(s); ret=dtls1_send_hello_request(s); if (ret <= 0) goto end; s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C; s->state=SSL3_ST_SW_FLUSH; s->init_num=0; ssl3_init_finished_mac(s); break; case SSL3_ST_SW_HELLO_REQ_C: s->state=SSL_ST_OK; break; case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: case SSL3_ST_SR_CLNT_HELLO_C: s->shutdown=0; ret=ssl3_get_client_hello(s); if (ret <= 0) goto end; dtls1_stop_timer(s); if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; else s->state = SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; /* Reflect ClientHello sequence to remain stateless while listening */ if (listen) { memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence)); } /* If we're just listening, stop here */ if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { ret = 2; s->d1->listen = 0; /* Set expected sequence numbers * to continue the handshake. */ s->d1->handshake_read_seq = 2; s->d1->handshake_write_seq = 1; s->d1->next_handshake_write_seq = 1; goto end; } break; case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: ret = dtls1_send_hello_verify_request(s); if ( ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; /* HelloVerifyRequests resets Finished MAC */ if (s->client_version != DTLS1_BAD_VER) ssl3_init_finished_mac(s); break; case SSL3_ST_SW_SRVR_HELLO_A: case SSL3_ST_SW_SRVR_HELLO_B: s->new_session = 2; dtls1_start_timer(s); ret=dtls1_send_server_hello(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_TLSEXT if (s->hit) { if (s->tlsext_ticket_expected) s->state=SSL3_ST_SW_SESSION_TICKET_A; else s->state=SSL3_ST_SW_CHANGE_A; } #else if (s->hit) s->state=SSL3_ST_SW_CHANGE_A; #endif else s->state=SSL3_ST_SW_CERT_A; s->init_num=0; break; case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: /* Check if it is anon DH */ if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) { dtls1_start_timer(s); ret=dtls1_send_server_certificate(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_TLSEXT if (s->tlsext_status_expected) s->state=SSL3_ST_SW_CERT_STATUS_A; else s->state=SSL3_ST_SW_KEY_EXCH_A; } else { skip = 1; s->state=SSL3_ST_SW_KEY_EXCH_A; } #else } else skip=1; s->state=SSL3_ST_SW_KEY_EXCH_A; #endif s->init_num=0; break; case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: l=s->s3->tmp.new_cipher->algorithms; /* clear this, it may get reset by * send_server_key_exchange */ if ((s->options & SSL_OP_EPHEMERAL_RSA) #ifndef OPENSSL_NO_KRB5 && !(l & SSL_KRB5) #endif /* OPENSSL_NO_KRB5 */ ) /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key * even when forbidden by protocol specs * (handshake may fail as clients are not required to * be able to handle this) */ s->s3->tmp.use_rsa_tmp=1; else s->s3->tmp.use_rsa_tmp=0; /* only send if a DH key exchange, fortezza or * RSA but we have a sign only certificate */ if (s->s3->tmp.use_rsa_tmp || (l & (SSL_DH|SSL_kFZA)) || ((l & SSL_kRSA) && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) ) ) ) ) { dtls1_start_timer(s); ret=dtls1_send_server_key_exchange(s); if (ret <= 0) goto end; } else skip=1; s->state=SSL3_ST_SW_CERT_REQ_A; s->init_num=0; break; case SSL3_ST_SW_CERT_REQ_A: case SSL3_ST_SW_CERT_REQ_B: if (/* don't request cert unless asked for it: */ !(s->verify_mode & SSL_VERIFY_PEER) || /* if SSL_VERIFY_CLIENT_ONCE is set, * don't request cert during re-negotiation: */ ((s->session->peer != NULL) && (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || /* never request cert in anonymous ciphersuites * (see section "Certificate request" in SSL 3 drafts * and in RFC 2246): */ ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) && /* ... except when the application insists on verification * (against the specs, but s3_clnt.c accepts this for SSL 3) */ !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || /* never request cert in Kerberos ciphersuites */ (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)) { /* no cert request */ skip=1; s->s3->tmp.cert_request=0; s->state=SSL3_ST_SW_SRVR_DONE_A; } else { s->s3->tmp.cert_request=1; dtls1_start_timer(s); ret=dtls1_send_certificate_request(s); if (ret <= 0) goto end; #ifndef NETSCAPE_HANG_BUG s->state=SSL3_ST_SW_SRVR_DONE_A; #else s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; #endif s->init_num=0; } break; case SSL3_ST_SW_SRVR_DONE_A: case SSL3_ST_SW_SRVR_DONE_B: dtls1_start_timer(s); ret=dtls1_send_server_done(s); if (ret <= 0) goto end; s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; s->state=SSL3_ST_SW_FLUSH; s->init_num=0; break; case SSL3_ST_SW_FLUSH: s->rwstate=SSL_WRITING; if (BIO_flush(s->wbio) <= 0) { ret= -1; goto end; } s->rwstate=SSL_NOTHING; s->state=s->s3->tmp.next_state; break; case SSL3_ST_SR_CERT_A: case SSL3_ST_SR_CERT_B: /* Check for second client hello (MS SGC) */ ret = ssl3_check_client_hello(s); if (ret <= 0) goto end; dtls1_stop_timer(s); if (ret == 2) s->state = SSL3_ST_SR_CLNT_HELLO_C; else { /* could be sent for a DH cert, even if we * have not asked for it :-) */ ret=ssl3_get_client_certificate(s); if (ret <= 0) goto end; dtls1_stop_timer(s); s->init_num=0; s->state=SSL3_ST_SR_KEY_EXCH_A; } break; case SSL3_ST_SR_KEY_EXCH_A: case SSL3_ST_SR_KEY_EXCH_B: ret=ssl3_get_client_key_exchange(s); if (ret <= 0) goto end; dtls1_stop_timer(s); s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; /* We need to get hashes here so if there is * a client cert, it can be verified */ s->method->ssl3_enc->cert_verify_mac(s, &(s->s3->finish_dgst1), &(s->s3->tmp.cert_verify_md[0])); s->method->ssl3_enc->cert_verify_mac(s, &(s->s3->finish_dgst2), &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); break; case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: s->d1->change_cipher_spec_ok = 1; /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; dtls1_stop_timer(s); s->state=SSL3_ST_SR_FINISHED_A; s->init_num=0; break; case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: s->d1->change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; dtls1_stop_timer(s); if (s->hit) s->state=SSL_ST_OK; #ifndef OPENSSL_NO_TLSEXT else if (s->tlsext_ticket_expected) s->state=SSL3_ST_SW_SESSION_TICKET_A; #endif else s->state=SSL3_ST_SW_CHANGE_A; s->init_num=0; break; #ifndef OPENSSL_NO_TLSEXT case SSL3_ST_SW_SESSION_TICKET_A: case SSL3_ST_SW_SESSION_TICKET_B: ret=dtls1_send_newsession_ticket(s); if (ret <= 0) goto end; s->state=SSL3_ST_SW_CHANGE_A; s->init_num=0; break; case SSL3_ST_SW_CERT_STATUS_A: case SSL3_ST_SW_CERT_STATUS_B: ret=ssl3_send_cert_status(s); if (ret <= 0) goto end; s->state=SSL3_ST_SW_KEY_EXCH_A; s->init_num=0; break; #endif case SSL3_ST_SW_CHANGE_A: case SSL3_ST_SW_CHANGE_B: s->session->cipher=s->s3->tmp.new_cipher; if (!s->method->ssl3_enc->setup_key_block(s)) { ret= -1; goto end; } ret=dtls1_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B); if (ret <= 0) goto end; s->state=SSL3_ST_SW_FINISHED_A; s->init_num=0; if (!s->method->ssl3_enc->change_cipher_state(s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { ret= -1; goto end; } dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); break; case SSL3_ST_SW_FINISHED_A: case SSL3_ST_SW_FINISHED_B: ret=dtls1_send_finished(s, SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B, s->method->ssl3_enc->server_finished_label, s->method->ssl3_enc->server_finished_label_len); if (ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; if (s->hit) s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; else s->s3->tmp.next_state=SSL_ST_OK; s->init_num=0; break; case SSL_ST_OK: /* clean a few things up */ ssl3_cleanup_key_block(s); #if 0 BUF_MEM_free(s->init_buf); s->init_buf=NULL; #endif /* remove buffering on output */ ssl_free_wbio_buffer(s); s->init_num=0; if (s->new_session == 2) /* skipped if we just sent a HelloRequest */ { /* actually not necessarily a 'new' session unless * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ s->new_session=0; ssl_update_cache(s,SSL_SESS_CACHE_SERVER); s->ctx->stats.sess_accept_good++; /* s->server=1; */ s->handshake_func=dtls1_accept; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); } ret = 1; /* done handshaking, next message is client hello */ s->d1->handshake_read_seq = 0; /* next message is server hello */ s->d1->handshake_write_seq = 0; s->d1->next_handshake_write_seq = 0; goto end; /* break; */ default: SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE); ret= -1; goto end; /* break; */ }
size_t ccn_sigc_signature_max_size(struct ccn_sigc *ctx, const struct ccn_pkey *priv_key) { return (EVP_PKEY_size((EVP_PKEY *)priv_key)); }
int dtls1_accept(SSL *s) { BUF_MEM *buf; unsigned long Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; unsigned long alg_k; int ret= -1; int new_state,state,skip=0; int listen; #ifndef OPENSSL_NO_SCTP unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; #endif RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; listen = s->d1->listen; /* init things to blank */ s->in_handshake++; if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); s->d1->listen = listen; #ifndef OPENSSL_NO_SCTP /* Notify SCTP BIO socket to enter handshake * mode and prevent stream identifier other * than 0. Will be ignored if no SCTP is used. */ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL); #endif if (s->cert == NULL) { SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET); return(-1); } #ifndef OPENSSL_NO_HEARTBEATS /* If we're awaiting a HeartbeatResponse, pretend we * already got and don't await it anymore, because * Heartbeats don't make sense during handshakes anyway. */ if (s->tlsext_hb_pending) { dtls1_stop_timer(s); s->tlsext_hb_pending = 0; s->tlsext_hb_seq++; } #endif for (;;) { state=s->state; switch (s->state) { case SSL_ST_RENEGOTIATE: s->renegotiate=1; /* s->state=SSL_ST_ACCEPT; */ case SSL_ST_BEFORE: case SSL_ST_ACCEPT: case SSL_ST_BEFORE|SSL_ST_ACCEPT: case SSL_ST_OK|SSL_ST_ACCEPT: s->server=1; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); return -1; } s->type=SSL_ST_ACCEPT; if (s->init_buf == NULL) { if ((buf=BUF_MEM_new()) == NULL) { ret= -1; goto end; } if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) { ret= -1; goto end; } s->init_buf=buf; } if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } s->init_num=0; if (s->state != SSL_ST_RENEGOTIATE) { /* Ok, we now need to push on a buffering BIO so that * the output is sent in a way that TCP likes :-) * ...but not with SCTP :-) */ #ifndef OPENSSL_NO_SCTP if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) #endif if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } ssl3_init_finished_mac(s); s->state=SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else { /* s->state == SSL_ST_RENEGOTIATE, * we will just send a HelloRequest */ s->ctx->stats.sess_accept_renegotiate++; s->state=SSL3_ST_SW_HELLO_REQ_A; } break; case SSL3_ST_SW_HELLO_REQ_A: case SSL3_ST_SW_HELLO_REQ_B: s->shutdown=0; dtls1_clear_record_buffer(s); dtls1_start_timer(s); ret=ssl3_send_hello_request(s); if (ret <= 0) goto end; s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; s->state=SSL3_ST_SW_FLUSH; s->init_num=0; ssl3_init_finished_mac(s); break; case SSL3_ST_SW_HELLO_REQ_C: s->state=SSL_ST_OK; break; case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: case SSL3_ST_SR_CLNT_HELLO_C: s->shutdown=0; ret=ssl3_get_client_hello(s); if (ret <= 0) goto end; dtls1_stop_timer(s); if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; else s->state = SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; /* Reflect ClientHello sequence to remain stateless while listening */ if (listen) { memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence)); } /* If we're just listening, stop here */ if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { ret = 2; s->d1->listen = 0; /* Set expected sequence numbers * to continue the handshake. */ s->d1->handshake_read_seq = 2; s->d1->handshake_write_seq = 1; s->d1->next_handshake_write_seq = 1; goto end; } break; case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: ret = dtls1_send_hello_verify_request(s); if ( ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; /* HelloVerifyRequest resets Finished MAC */ if (s->version != DTLS1_BAD_VER) ssl3_init_finished_mac(s); break; #ifndef OPENSSL_NO_SCTP case DTLS1_SCTP_ST_SR_READ_SOCK: if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { s->s3->in_read_app_data=2; s->rwstate=SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); ret = -1; goto end; } s->state=SSL3_ST_SR_FINISHED_A; break; case DTLS1_SCTP_ST_SW_WRITE_SOCK: ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); if (ret < 0) goto end; if (ret == 0) { if (s->d1->next_state != SSL_ST_OK) { s->s3->in_read_app_data=2; s->rwstate=SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); ret = -1; goto end; } } s->state=s->d1->next_state; break; #endif case SSL3_ST_SW_SRVR_HELLO_A: case SSL3_ST_SW_SRVR_HELLO_B: s->renegotiate = 2; dtls1_start_timer(s); ret=ssl3_send_server_hello(s); if (ret <= 0) goto end; if (s->hit) { #ifndef OPENSSL_NO_SCTP /* Add new shared key for SCTP-Auth, * will be ignored if no SCTP used. */ snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), DTLS1_SCTP_AUTH_LABEL); SSL_export_keying_material(s, sctpauthkey, sizeof(sctpauthkey), labelbuffer, sizeof(labelbuffer), NULL, 0, 0); BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, sizeof(sctpauthkey), sctpauthkey); #endif #ifndef OPENSSL_NO_TLSEXT if (s->tlsext_ticket_expected) s->state=SSL3_ST_SW_SESSION_TICKET_A; else s->state=SSL3_ST_SW_CHANGE_A; #else s->state=SSL3_ST_SW_CHANGE_A; #endif } else s->state=SSL3_ST_SW_CERT_A; s->init_num=0; break; case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: /* Check if it is anon DH or normal PSK */ if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { dtls1_start_timer(s); ret=ssl3_send_server_certificate(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_TLSEXT if (s->tlsext_status_expected) s->state=SSL3_ST_SW_CERT_STATUS_A; else s->state=SSL3_ST_SW_KEY_EXCH_A; } else { skip = 1; s->state=SSL3_ST_SW_KEY_EXCH_A; } #else } else skip=1; s->state=SSL3_ST_SW_KEY_EXCH_A; #endif s->init_num=0; break; case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: alg_k = s->s3->tmp.new_cipher->algorithm_mkey; /* clear this, it may get reset by * send_server_key_exchange */ if ((s->options & SSL_OP_EPHEMERAL_RSA) #ifndef OPENSSL_NO_KRB5 && !(alg_k & SSL_kKRB5) #endif /* OPENSSL_NO_KRB5 */ ) /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key * even when forbidden by protocol specs * (handshake may fail as clients are not required to * be able to handle this) */ s->s3->tmp.use_rsa_tmp=1; else s->s3->tmp.use_rsa_tmp=0; /* only send if a DH key exchange or * RSA but we have a sign only certificate */ if (s->s3->tmp.use_rsa_tmp /* PSK: send ServerKeyExchange if PSK identity * hint if provided */ #ifndef OPENSSL_NO_PSK || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) #endif || (alg_k & (SSL_kDHE|SSL_kDHr|SSL_kDHd)) || (alg_k & SSL_kECDHE) || ((alg_k & SSL_kRSA) && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) ) ) ) ) { dtls1_start_timer(s); ret=ssl3_send_server_key_exchange(s); if (ret <= 0) goto end; } else skip=1; s->state=SSL3_ST_SW_CERT_REQ_A; s->init_num=0; break; case SSL3_ST_SW_CERT_REQ_A: case SSL3_ST_SW_CERT_REQ_B: if (/* don't request cert unless asked for it: */ !(s->verify_mode & SSL_VERIFY_PEER) || /* if SSL_VERIFY_CLIENT_ONCE is set, * don't request cert during re-negotiation: */ ((s->session->peer != NULL) && (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || /* never request cert in anonymous ciphersuites * (see section "Certificate request" in SSL 3 drafts * and in RFC 2246): */ ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && /* ... except when the application insists on verification * (against the specs, but s3_clnt.c accepts this for SSL 3) */ !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || /* never request cert in Kerberos ciphersuites */ (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) /* With normal PSK Certificates and * Certificate Requests are omitted */ || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { /* no cert request */ skip=1; s->s3->tmp.cert_request=0; s->state=SSL3_ST_SW_SRVR_DONE_A; #ifndef OPENSSL_NO_SCTP if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; } #endif } else { s->s3->tmp.cert_request=1; dtls1_start_timer(s); ret=ssl3_send_certificate_request(s); if (ret <= 0) goto end; #ifndef NETSCAPE_HANG_BUG s->state=SSL3_ST_SW_SRVR_DONE_A; #ifndef OPENSSL_NO_SCTP if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; } #endif #else s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; #ifndef OPENSSL_NO_SCTP if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { s->d1->next_state = s->s3->tmp.next_state; s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK; } #endif #endif s->init_num=0; } break; case SSL3_ST_SW_SRVR_DONE_A: case SSL3_ST_SW_SRVR_DONE_B: dtls1_start_timer(s); ret=ssl3_send_server_done(s); if (ret <= 0) goto end; s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; s->state=SSL3_ST_SW_FLUSH; s->init_num=0; break; case SSL3_ST_SW_FLUSH: s->rwstate=SSL_WRITING; if (BIO_flush(s->wbio) <= 0) { /* If the write error was fatal, stop trying */ if (!BIO_should_retry(s->wbio)) { s->rwstate=SSL_NOTHING; s->state=s->s3->tmp.next_state; } ret= -1; goto end; } s->rwstate=SSL_NOTHING; s->state=s->s3->tmp.next_state; break; case SSL3_ST_SR_CERT_A: case SSL3_ST_SR_CERT_B: /* Check for second client hello (MS SGC) */ ret = ssl3_check_client_hello(s); if (ret <= 0) goto end; if (ret == 2) { dtls1_stop_timer(s); s->state = SSL3_ST_SR_CLNT_HELLO_C; } else { /* could be sent for a DH cert, even if we * have not asked for it :-) */ ret=ssl3_get_client_certificate(s); if (ret <= 0) goto end; s->init_num=0; s->state=SSL3_ST_SR_KEY_EXCH_A; } break; case SSL3_ST_SR_KEY_EXCH_A: case SSL3_ST_SR_KEY_EXCH_B: ret=ssl3_get_client_key_exchange(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_SCTP /* Add new shared key for SCTP-Auth, * will be ignored if no SCTP used. */ snprintf((char *) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), DTLS1_SCTP_AUTH_LABEL); SSL_export_keying_material(s, sctpauthkey, sizeof(sctpauthkey), labelbuffer, sizeof(labelbuffer), NULL, 0, 0); BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, sizeof(sctpauthkey), sctpauthkey); #endif s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; if (ret == 2) { /* For the ECDH ciphersuites when * the client sends its ECDH pub key in * a certificate, the CertificateVerify * message is not sent. */ s->state=SSL3_ST_SR_FINISHED_A; s->init_num = 0; } else if (SSL_USE_SIGALGS(s)) { s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; if (!s->session->peer) break; /* For sigalgs freeze the handshake buffer * at this point and digest cached records. */ if (!s->s3->handshake_buffer) { SSLerr(SSL_F_DTLS1_ACCEPT,ERR_R_INTERNAL_ERROR); return -1; } s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; if (!ssl3_digest_cached_records(s)) return -1; } else { s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; /* We need to get hashes here so if there is * a client cert, it can be verified */ s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(s->s3->tmp.cert_verify_md[0])); s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); } break; case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: s->d1->change_cipher_spec_ok = 1; /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_SCTP if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && state == SSL_ST_RENEGOTIATE) s->state=DTLS1_SCTP_ST_SR_READ_SOCK; else #endif s->state=SSL3_ST_SR_FINISHED_A; s->init_num=0; break; case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: s->d1->change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; dtls1_stop_timer(s); if (s->hit) s->state=SSL_ST_OK; #ifndef OPENSSL_NO_TLSEXT else if (s->tlsext_ticket_expected) s->state=SSL3_ST_SW_SESSION_TICKET_A; #endif else s->state=SSL3_ST_SW_CHANGE_A; s->init_num=0; break; #ifndef OPENSSL_NO_TLSEXT case SSL3_ST_SW_SESSION_TICKET_A: case SSL3_ST_SW_SESSION_TICKET_B: ret=ssl3_send_newsession_ticket(s); if (ret <= 0) goto end; s->state=SSL3_ST_SW_CHANGE_A; s->init_num=0; break; case SSL3_ST_SW_CERT_STATUS_A: case SSL3_ST_SW_CERT_STATUS_B: ret=ssl3_send_cert_status(s); if (ret <= 0) goto end; s->state=SSL3_ST_SW_KEY_EXCH_A; s->init_num=0; break; #endif case SSL3_ST_SW_CHANGE_A: case SSL3_ST_SW_CHANGE_B: s->session->cipher=s->s3->tmp.new_cipher; if (!s->method->ssl3_enc->setup_key_block(s)) { ret= -1; goto end; } ret=dtls1_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B); if (ret <= 0) goto end; #ifndef OPENSSL_NO_SCTP if (!s->hit) { /* Change to new shared key of SCTP-Auth, * will be ignored if no SCTP used. */ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); } #endif s->state=SSL3_ST_SW_FINISHED_A; s->init_num=0; if (!s->method->ssl3_enc->change_cipher_state(s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { ret= -1; goto end; } dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); break; case SSL3_ST_SW_FINISHED_A: case SSL3_ST_SW_FINISHED_B: ret=ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B, s->method->ssl3_enc->server_finished_label, s->method->ssl3_enc->server_finished_label_len); if (ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; if (s->hit) { s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; #ifndef OPENSSL_NO_SCTP /* Change to new shared key of SCTP-Auth, * will be ignored if no SCTP used. */ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); #endif } else { s->s3->tmp.next_state=SSL_ST_OK; #ifndef OPENSSL_NO_SCTP if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { s->d1->next_state = s->s3->tmp.next_state; s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK; } #endif } s->init_num=0; break; case SSL_ST_OK: /* clean a few things up */ ssl3_cleanup_key_block(s); #if 0 BUF_MEM_free(s->init_buf); s->init_buf=NULL; #endif /* remove buffering on output */ ssl_free_wbio_buffer(s); s->init_num=0; if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */ { s->renegotiate=0; s->new_session=0; ssl_update_cache(s,SSL_SESS_CACHE_SERVER); s->ctx->stats.sess_accept_good++; /* s->server=1; */ s->handshake_func=dtls1_accept; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); } ret = 1; /* done handshaking, next message is client hello */ s->d1->handshake_read_seq = 0; /* next message is server hello */ s->d1->handshake_write_seq = 0; s->d1->next_handshake_write_seq = 0; goto end; /* break; */ default: SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE); ret= -1; goto end; /* break; */ }
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, const EVP_MD *type) { EVP_MD_CTX ctx; unsigned char *p, *buf_in = NULL, *buf_out = NULL; int i, inl = 0, outl = 0, outll = 0; X509_ALGOR *a; EVP_MD_CTX_init(&ctx); for (i = 0; i < 2; i++) { if (i == 0) a = algor1; else a = algor2; if (a == NULL) continue; if (type->pkey_type == NID_dsaWithSHA1) { /* * special case: RFC 2459 tells us to omit 'parameters' with * id-dsa-with-sha1 */ ASN1_TYPE_free(a->parameter); a->parameter = NULL; } else if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) { ASN1_TYPE_free(a->parameter); if ((a->parameter = ASN1_TYPE_new()) == NULL) goto err; a->parameter->type = V_ASN1_NULL; } ASN1_OBJECT_free(a->algorithm); a->algorithm = OBJ_nid2obj(type->pkey_type); if (a->algorithm == NULL) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); goto err; } if (a->algorithm->length == 0) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); goto err; } } inl = i2d(data, NULL); buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl); outll = outl = EVP_PKEY_size(pkey); buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; i2d(data, &p); if (!EVP_SignInit_ex(&ctx, type, NULL) || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl) || !EVP_SignFinal(&ctx, (unsigned char *)buf_out, (unsigned int *)&outl, pkey)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, 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 EVP_PKEY_CTX * init_ctx(int *pkeysize, char *keyfile, int keyform, int key_type, char *passargin, int pkey_op) { EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *passin = NULL; int rv = -1; X509 *x; if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) || (pkey_op == EVP_PKEY_OP_DERIVE)) && (key_type != KEY_PRIVKEY)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } switch (key_type) { case KEY_PRIVKEY: pkey = load_key(bio_err, keyfile, keyform, 0, passin, "Private Key"); break; case KEY_PUBKEY: pkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, "Public Key"); break; case KEY_CERT: x = load_cert(bio_err, keyfile, keyform, NULL, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); } break; } *pkeysize = EVP_PKEY_size(pkey); if (!pkey) goto end; ctx = EVP_PKEY_CTX_new(pkey, NULL); EVP_PKEY_free(pkey); if (!ctx) goto end; switch (pkey_op) { case EVP_PKEY_OP_SIGN: rv = EVP_PKEY_sign_init(ctx); break; case EVP_PKEY_OP_VERIFY: rv = EVP_PKEY_verify_init(ctx); break; case EVP_PKEY_OP_VERIFYRECOVER: rv = EVP_PKEY_verify_recover_init(ctx); break; case EVP_PKEY_OP_ENCRYPT: rv = EVP_PKEY_encrypt_init(ctx); break; case EVP_PKEY_OP_DECRYPT: rv = EVP_PKEY_decrypt_init(ctx); break; case EVP_PKEY_OP_DERIVE: rv = EVP_PKEY_derive_init(ctx); break; } if (rv <= 0) { EVP_PKEY_CTX_free(ctx); ctx = NULL; } end: free(passin); return ctx; }
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); }
int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile, const char *file, const char *signer_name) { FILE *fp = NULL; BIO *sigbio; int siglen = 0; int i; unsigned char *sigbuf = NULL; char *msg = NULL; int size; size_t rbytes; int status = 0; (void)signer_name; if (!dgst) { ERROR("Wrong crypto initialization: did you pass the key ?"); status = -ENOKEY; goto out; } msg = malloc(BUFSIZE); if (!msg) { status = -ENOMEM; goto out; } sigbio = BIO_new_file(sigfile, "rb"); siglen = EVP_PKEY_size(dgst->pkey); sigbuf = OPENSSL_malloc(siglen); siglen = BIO_read(sigbio, sigbuf, siglen); BIO_free(sigbio); if(siglen <= 0) { ERROR("Error reading signature file %s", sigfile); status = -ENOKEY; goto out; } if ((dgst_init(dgst, EVP_sha256()) < 0) || (dgst_verify_init(dgst) < 0)) { status = -ENOKEY; goto out; } fp = fopen(file, "r"); if (!fp) { ERROR("%s cannot be opened", file); status = -EBADF; goto out; } size = 0; for (;;) { rbytes = fread(msg, 1, BUFSIZE, fp); if (rbytes > 0) { size += rbytes; if (verify_update(dgst, msg, rbytes) < 0) break; } if (feof(fp)) break; } TRACE("Verify signed image: Read %d bytes", size); i = verify_final(dgst, sigbuf, (unsigned int)siglen); if(i > 0) { TRACE("Verified OK"); status = 0; } else if(i == 0) { TRACE("Verification Failure"); status = -EBADMSG; } else { TRACE("Error Verifying Data"); status = -EFAULT; } out: if (fp) fclose(fp); if (msg) free(msg); if (sigbuf) OPENSSL_free(sigbuf); return status; }
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out=NULL,*btmp=NULL; X509_ALGOR *xa = NULL; const EVP_CIPHER *evp_cipher=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; EVP_PKEY *pkey; ASN1_OCTET_STRING *os=NULL; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk=p7->d.sign->md_algs; os = PKCS7_get_octet_string(p7->d.sign->contents); break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; xalg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; xalg=p7->d.enveloped->enc_data->algorithm; evp_cipher=p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_digest: xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) goto err; if (xa && !PKCS7_bio_add_digest(&out, xa)) goto err; if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen,ivlen; int jj,max; unsigned char *tmp; EVP_CIPHER_CTX *ctx; if ((btmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen=EVP_CIPHER_key_length(evp_cipher); ivlen=EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) goto err; if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) goto err; if (ivlen > 0) { if (xalg->parameter == NULL) xalg->parameter=ASN1_TYPE_new(); if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ max=0; for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (ri->cert == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); goto err; } pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_size(pkey); EVP_PKEY_free(pkey); if (max < jj) max=jj; } if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); goto err; } for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); EVP_PKEY_free(pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); OPENSSL_free(tmp); goto err; } if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj)) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp); goto err; } } OPENSSL_free(tmp); OPENSSL_cleanse(key, keylen); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio=BIO_new(BIO_s_null()); else if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if(bio == NULL) { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } } BIO_push(out,bio); bio=NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out=NULL; } return(out); }