static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) { unsigned char *p; unsigned int bitlen, magic = 0, keyalg; int outlen, noinc = 0; int pktype = EVP_PKEY_id(pk); if (pktype == EVP_PKEY_DSA) { bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic); keyalg = MS_KEYALG_DSS_SIGN; } else if (pktype == EVP_PKEY_RSA) { bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic); keyalg = MS_KEYALG_RSA_KEYX; } else return -1; if (bitlen == 0) return -1; outlen = 16 + blob_length(bitlen, keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); if (out == NULL) return outlen; if (*out) p = *out; else { if ((p = OPENSSL_malloc(outlen)) == NULL) { PEMerr(PEM_F_DO_I2B, ERR_R_MALLOC_FAILURE); return -1; } *out = p; noinc = 1; } if (ispub) *p++ = MS_PUBLICKEYBLOB; else *p++ = MS_PRIVATEKEYBLOB; *p++ = 0x2; *p++ = 0; *p++ = 0; write_ledword(&p, keyalg); write_ledword(&p, magic); write_ledword(&p, bitlen); if (keyalg == MS_KEYALG_DSS_SIGN) write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub); else write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub); if (!noinc) *out += outlen; return outlen; }
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { RSA *rsa = EVP_PKEY_get0_RSA(pkey); if (rsa != NULL) { RSA_up_ref(rsa); } return rsa; }
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { RSA *ret = EVP_PKEY_get0_RSA(pkey); if (ret != NULL) RSA_up_ref(ret); return ret; }
static int ssl_set_cert(CERT *c, X509 *x) { EVP_PKEY *pkey; int i; pkey = X509_get0_pubkey(x); if (pkey == NULL) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); return (0); } i = ssl_cert_type(x, pkey); if (i < 0) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } #ifndef OPENSSL_NO_EC if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; } #endif if (c->pkeys[i].privatekey != NULL) { /* * The return code from EVP_PKEY_copy_parameters is deliberately * ignored. Some EVP_PKEY types cannot do this. */ EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); ERR_clear_error(); #ifndef OPENSSL_NO_RSA /* * Don't check the public/private key, this is mostly for smart * cards. */ if (EVP_PKEY_id(c->pkeys[i].privatekey) == EVP_PKEY_RSA && RSA_flags(EVP_PKEY_get0_RSA(c->pkeys[i].privatekey)) & RSA_METHOD_FLAG_NO_CHECK) ; else #endif /* OPENSSL_NO_RSA */ if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { /* * don't fail for a cert/key mismatch, just free current private * key (when switching to a different cert & key, first this * function should be used, then ssl_set_pkey */ EVP_PKEY_free(c->pkeys[i].privatekey); c->pkeys[i].privatekey = NULL; /* clear error queue */ ERR_clear_error(); } } X509_free(c->pkeys[i].x509); X509_up_ref(x); c->pkeys[i].x509 = x; c->key = &(c->pkeys[i]); return 1; }
/** Low-level signature verification. * \param key_count Number of keys in the \a keys array * and number fo signatures in the \a sigs array. * \param keys Array of keys. The keys must include public key data. * \param sigs Array of signatures, as returned from gale_crypto_sign_raw(). * \param data Data to verify against signatures. * \return Nonzero iff the all signatures are valid. */ int gale_crypto_verify_raw(int key_count, const struct gale_group *keys, const struct gale_data *sigs, struct gale_data data) { int i,is_valid = 1; EVP_MD_CTX *context = EVP_MD_CTX_new(); RSA *rsa; EVP_VerifyInit(context,EVP_md5()); EVP_VerifyUpdate(context,data.p,data.l); for (i = 0; is_valid && 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(keys[i],rsa); if (!crypto_i_public_valid(rsa)) { gale_alert(GALE_WARNING,G_("invalid public key"),0); is_valid = 0; goto cleanup; } if (!EVP_VerifyFinal(context,sigs[i].p,sigs[i].l,key)) { crypto_i_error(); is_valid = 0; goto cleanup; } cleanup: EVP_PKEY_free(key); } return is_valid; }
static int xmlSecOpenSSLRsaOaepSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecOpenSSLRsaOaepCtxPtr ctx; EVP_PKEY* pKey; RSA *rsa; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecOpenSSLKeyDataRsaId), -1); ctx = xmlSecOpenSSLRsaOaepGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pKey == NULL, -1); pKey = xmlSecOpenSSLKeyDataRsaGetEvp(xmlSecKeyGetValue(key)); if(pKey == NULL) { xmlSecInternalError("xmlSecOpenSSLKeyDataRsaGetEvp", xmlSecTransformGetName(transform)); return(-1); } xmlSecAssert2(EVP_PKEY_base_id(pKey) == EVP_PKEY_RSA, -1); rsa = EVP_PKEY_get0_RSA(pKey); xmlSecAssert2(rsa != NULL, -1); ctx->pKey = xmlSecOpenSSLEvpKeyDup(pKey); if(ctx->pKey == NULL) { xmlSecInternalError("xmlSecOpenSSLEvpKeyDup", xmlSecTransformGetName(transform)); return(-1); } return(0); }
static int cardfingerprint(void *ctx,char *file,void *out) { int r=NOCARD; int len; EVP_PKEY *key; RSA *rsa=NULL; EC_KEY *ec=NULL; ENGINE *e=(ENGINE *)ctx; unsigned char bfr[2048]; unsigned char *p=bfr; resume_engine(e,engbits); if(!(key=ENGINE_load_public_key(e,file,NULL,NULL)))goto err1; r=CRYPTOFAIL; #if OPENSSL_VERSION_NUMBER >= 0x1010000fL if(EVP_PKEY_get0_RSA(key)) { if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err2; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err3; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err3; } else if(EVP_PKEY_get0_EC_KEY(key)) { if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err2; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err3; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err3; } else goto err2; #else switch(EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err2; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err3; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err3; break; case EVP_PKEY_EC: if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err2; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err3; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err3; break; default:goto err2; } #endif if(out)sha256(bfr,len,out); r=OK; err3: if(rsa)RSA_free(rsa); if(ec)EC_KEY_free(ec); memclear(bfr,0,sizeof(bfr)); err2: EVP_PKEY_free(key); err1: suspend_engine(e,&engbits); return r; }
static RSA *pkcs11_rsa(PKCS11_KEY *key) { EVP_PKEY *evp_key = pkcs11_get_key(key, key->isPrivate); RSA *rsa; if (evp_key == NULL) return NULL; rsa = EVP_PKEY_get0_RSA(evp_key); EVP_PKEY_free(evp_key); return rsa; }
static EVP_MD_CTX * setup(jose_cfg_t *cfg, const json_t *jwk, const json_t *sig, const char *alg, init_t *func) { openssl_auto(EVP_PKEY) *key = NULL; EVP_PKEY_CTX *epc = NULL; const EVP_MD *md = NULL; EVP_MD_CTX *emc = NULL; const RSA *rsa = NULL; int slen = 0; int pad = 0; switch (str2enum(alg, NAMES, NULL)) { case 0: md = EVP_sha256(); pad = RSA_PKCS1_PADDING; break; case 1: md = EVP_sha384(); pad = RSA_PKCS1_PADDING; break; case 2: md = EVP_sha512(); pad = RSA_PKCS1_PADDING; break; case 3: md = EVP_sha256(); pad = RSA_PKCS1_PSS_PADDING; slen = -1; break; case 4: md = EVP_sha384(); pad = RSA_PKCS1_PSS_PADDING; slen = -1; break; case 5: md = EVP_sha512(); pad = RSA_PKCS1_PSS_PADDING; slen = -1; break; default: return NULL; } key = jose_openssl_jwk_to_EVP_PKEY(cfg, jwk); if (!key || EVP_PKEY_base_id(key) != EVP_PKEY_RSA) return NULL; /* Don't use small keys. RFC 7518 3.3 */ rsa = EVP_PKEY_get0_RSA(key); if (!rsa) return NULL; if (RSA_size(rsa) < 2048 / 8) return NULL; emc = EVP_MD_CTX_new(); if (!emc) return NULL; if (func(emc, &epc, md, NULL, key) <= 0) goto error; if (EVP_PKEY_CTX_set_rsa_padding(epc, pad) <= 0) goto error; if (slen != 0) { if (EVP_PKEY_CTX_set_rsa_pss_saltlen(epc, slen) <= 0) goto error; } return emc; error: EVP_MD_CTX_free(emc); return NULL; }
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { int i; i = ssl_cert_type(NULL, pkey); if (i < 0) { SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return (0); } #ifndef OPENSSL_NO_GMTLS if (i == SSL_PKEY_SM2 && c->pkeys[SSL_PKEY_SM2_ENC].x509) i = SSL_PKEY_SM2_ENC; #endif if (c->pkeys[i].x509 != NULL) { EVP_PKEY *pktmp; pktmp = X509_get0_pubkey(c->pkeys[i].x509); if (pktmp == NULL) { SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); return 0; } /* * The return code from EVP_PKEY_copy_parameters is deliberately * ignored. Some EVP_PKEY types cannot do this. */ EVP_PKEY_copy_parameters(pktmp, pkey); ERR_clear_error(); #ifndef OPENSSL_NO_RSA /* * Don't check the public/private key, this is mostly for smart * cards. */ if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK) ; else #endif if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { X509_free(c->pkeys[i].x509); c->pkeys[i].x509 = NULL; return 0; } } EVP_PKEY_free(c->pkeys[i].privatekey); EVP_PKEY_up_ref(pkey); c->pkeys[i].privatekey = pkey; c->key = &(c->pkeys[i]); return (1); }
int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, EVP_PKEY *priv) { int ret = -1; #ifndef OPENSSL_NO_RSA if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) { #endif EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); #ifndef OPENSSL_NO_RSA goto err; } ret = RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv), RSA_PKCS1_PADDING); err: #endif return ret; }
int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp) { switch (EVP_PKEY_id(a)) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp); #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp); #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp); #endif default: ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return -1; } }
enum ssl_private_key_result_t ssl_private_key_decrypt( SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const uint8_t *in, size_t in_len) { if (ssl->cert->key_method != NULL) { return ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in, in_len); } RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey); if (rsa == NULL) { /* Decrypt operations are only supported for RSA keys. */ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return ssl_private_key_failure; } /* Decrypt with no padding. PKCS#1 padding will be removed as part * of the timing-sensitive code by the caller. */ if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) { return ssl_private_key_failure; } return ssl_private_key_success; }
/** 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; }
static int xmlSecOpenSSLRsaPkcs1Process(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLRsaPkcs1CtxPtr ctx; xmlSecBufferPtr in, out; xmlSecSize inSize, outSize; xmlSecSize keySize; RSA *rsa; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pKey != NULL, -1); xmlSecAssert2(EVP_PKEY_base_id(ctx->pKey) == EVP_PKEY_RSA, -1); rsa = EVP_PKEY_get0_RSA(ctx->pKey); xmlSecAssert2(rsa != NULL, -1); keySize = RSA_size(rsa); xmlSecAssert2(keySize > 0, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); xmlSecAssert2(outSize == 0, -1); /* the encoded size is equal to the keys size so we could not * process more than that */ if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) { xmlSecInvalidSizeLessThanError("Input data", inSize, keySize, xmlSecTransformGetName(transform)); return(-1); } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) { xmlSecInvalidSizeError("Input data", inSize, keySize, xmlSecTransformGetName(transform)); return(-1); } outSize = keySize; ret = xmlSecBufferSetMaxSize(out, outSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferSetMaxSize", xmlSecTransformGetName(transform), "size=%d", outSize); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), rsa, RSA_PKCS1_PADDING); if(ret <= 0) { xmlSecOpenSSLError2("RSA_public_encrypt", xmlSecTransformGetName(transform), "size=%lu", (unsigned long)inSize); return(-1); } outSize = ret; } else { ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), rsa, RSA_PKCS1_PADDING); if(ret <= 0) { xmlSecOpenSSLError2("RSA_private_decrypt", xmlSecTransformGetName(transform), "size=%lu", (unsigned long)inSize); return(-1); } outSize = ret; } ret = xmlSecBufferSetSize(out, outSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferSetSize", xmlSecTransformGetName(transform), "size=%d", outSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferRemoveHead", xmlSecTransformGetName(transform), "size=%d", inSize); return(-1); } return(0); }
static int xmlSecOpenSSLRsaOaepProcess(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLRsaOaepCtxPtr ctx; xmlSecSize paramsSize; xmlSecBufferPtr in, out; xmlSecSize inSize, outSize; xmlSecSize keySize; RSA *rsa; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLRsaOaepGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pKey != NULL, -1); xmlSecAssert2(EVP_PKEY_base_id(ctx->pKey) == EVP_PKEY_RSA, -1); rsa = EVP_PKEY_get0_RSA(ctx->pKey); xmlSecAssert2(rsa != NULL, -1); keySize = RSA_size(rsa); xmlSecAssert2(keySize > 0, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); xmlSecAssert2(outSize == 0, -1); /* the encoded size is equal to the keys size so we could not * process more than that */ if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) { xmlSecInvalidSizeLessThanError("Input data", inSize, keySize, xmlSecTransformGetName(transform)); return(-1); } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) { xmlSecInvalidSizeError("Input data", inSize, keySize, xmlSecTransformGetName(transform)); return(-1); } outSize = keySize; ret = xmlSecBufferSetMaxSize(out, outSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferSetMaxSize", xmlSecTransformGetName(transform), "size=%d", outSize); return(-1); } paramsSize = xmlSecBufferGetSize(&(ctx->oaepParams)); if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize == 0)) { /* encode w/o OAEPParams --> simple */ ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), rsa, RSA_PKCS1_OAEP_PADDING); if(ret <= 0) { xmlSecOpenSSLError("RSA_public_encrypt(RSA_PKCS1_OAEP_PADDING)", xmlSecTransformGetName(transform)); return(-1); } outSize = ret; } else if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize > 0)) { xmlSecAssert2(xmlSecBufferGetData(&(ctx->oaepParams)) != NULL, -1); /* add space for padding */ ret = xmlSecBufferSetMaxSize(in, keySize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferSetMaxSize", xmlSecTransformGetName(transform), "size=%d", keySize); return(-1); } /* add padding */ ret = RSA_padding_add_PKCS1_OAEP(xmlSecBufferGetData(in), keySize, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(&(ctx->oaepParams)), paramsSize); if(ret != 1) { xmlSecOpenSSLError("RSA_padding_add_PKCS1_OAEP", xmlSecTransformGetName(transform)); return(-1); } inSize = keySize; /* encode with OAEPParams */ ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), rsa, RSA_NO_PADDING); if(ret <= 0) { xmlSecOpenSSLError("RSA_public_encrypt(RSA_NO_PADDING)", xmlSecTransformGetName(transform)); return(-1); } outSize = ret; } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize == 0)) { ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), rsa, RSA_PKCS1_OAEP_PADDING); if(ret <= 0) { xmlSecOpenSSLError("RSA_private_decrypt(RSA_PKCS1_OAEP_PADDING)", xmlSecTransformGetName(transform)); return(-1); } outSize = ret; } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize != 0)) { BIGNUM * bn; bn = BN_new(); if(bn == NULL) { xmlSecOpenSSLError("BN_new()", xmlSecTransformGetName(transform)); return(-1); } ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), rsa, RSA_NO_PADDING); if(ret <= 0) { xmlSecOpenSSLError("RSA_private_decrypt(RSA_NO_PADDING)", xmlSecTransformGetName(transform)); BN_free(bn); return(-1); } outSize = ret; /* * the private decrypt w/o padding adds '0's at the begginning. * it's not clear for me can I simply skip all '0's from the * beggining so I have to do decode it back to BIGNUM and dump * buffer again */ if(BN_bin2bn(xmlSecBufferGetData(out), outSize, bn) == NULL) { xmlSecOpenSSLError2("BN_bin2bn", xmlSecTransformGetName(transform), "size=%lu", (unsigned long)outSize); BN_free(bn); return(-1); } ret = BN_bn2bin(bn, xmlSecBufferGetData(out)); if(ret <= 0) { xmlSecOpenSSLError("BN_bn2bin", xmlSecTransformGetName(transform)); BN_free(bn); return(-1); } BN_free(bn); outSize = ret; ret = RSA_padding_check_PKCS1_OAEP(xmlSecBufferGetData(out), outSize, xmlSecBufferGetData(out), outSize, keySize, xmlSecBufferGetData(&(ctx->oaepParams)), paramsSize); if(ret < 0) { xmlSecOpenSSLError("RSA_padding_check_PKCS1_OAEP", xmlSecTransformGetName(transform)); return(-1); } outSize = ret; } else { xmlSecOtherError3(XMLSEC_ERRORS_R_INVALID_OPERATION, xmlSecTransformGetName(transform), "Unexpected transform operation: %ld; paramsSize: %ld", (long int)transform->operation, (long int)paramsSize); return(-1); } ret = xmlSecBufferSetSize(out, outSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferSetSize", xmlSecTransformGetName(transform), "size=%d", outSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferRemoveHead", xmlSecTransformGetName(transform), "size=%d", inSize); return(-1); } return(0); }
/** Decrypt some data. * \param key Key to use for decryption. Use gale_crypto_target() to find the * keys you can use, pick one you own, and supply private key data. * \param data Encrypted group. Will be replaced by decrypted group. * \return Nonzero iff the operation succeeded. * \sa gale_crypto_seal(), gale_crypto_target() */ int gale_crypto_open(struct gale_group key,struct gale_group *cipher) { struct gale_fragment frag; struct gale_data data; unsigned char iv[IV_LEN]; u32 i,key_count; EVP_PKEY *private_key = NULL; RSA *rsa; struct gale_text raw_name; struct gale_data session_key,plain; EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new(); int length,is_successful = 0; if (gale_group_null(*cipher)) goto cleanup; frag = gale_group_first(*cipher); if (gale_text_compare(G_("security/encryption"),frag.name) || frag_data != frag.type) { gale_alert(GALE_WARNING,G_("can't decrypt unencrypted data"),0); goto cleanup; } data = frag.value.data; if (!gale_unpack_compare(&data,magic2,sizeof(magic2)) || !gale_unpack_copy(&data,iv,sizeof(iv)) || !gale_unpack_u32(&data,&key_count)) goto cleanup; private_key = EVP_PKEY_new(); EVP_PKEY_assign_RSA(private_key,RSA_new()); rsa = EVP_PKEY_get0_RSA(private_key); raw_name = key_i_swizzle(crypto_i_rsa(key,rsa)); if (!crypto_i_private_valid(rsa)) { gale_alert(GALE_WARNING,G_("invalid private key"),0); goto cleanup; } session_key = null_data; for (i = 0; i < key_count; ++i) { struct gale_text name; if (!gale_unpack_text(&data,&name)) goto cleanup; if (gale_text_compare(raw_name,name)) { if (!gale_unpack_skip(&data)) goto cleanup; continue; } if (!gale_unpack_u32(&data,&session_key.l)) goto cleanup; session_key.p = gale_malloc(session_key.l); if (!gale_unpack_copy(&data,session_key.p,session_key.l)) goto cleanup; } if (0 == session_key.l) { gale_alert(GALE_WARNING,G_("key doesn't fit encrypted data"),0); goto cleanup; } if (!EVP_OpenInit(context,EVP_des_ede3_cbc(), session_key.p,session_key.l,iv,private_key)) { crypto_i_error(); goto cleanup; } plain.p = gale_malloc(data.l); plain.l = 0; EVP_OpenUpdate(context,plain.p + plain.l,&length,data.p,data.l); plain.l += length; EVP_OpenFinal(context,plain.p + plain.l,&length); plain.l += length; if (!gale_unpack_u32(&plain,&i) || 0 != i || !gale_unpack_group(&plain,cipher)) { gale_alert(GALE_WARNING,G_("invalid encrypted data"),0); goto cleanup; } is_successful = 1; cleanup: if (NULL != private_key) EVP_PKEY_free(private_key); return is_successful; }
static bool alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe, json_t *rcp, const json_t *jwk, json_t *cek) { openssl_auto(EVP_PKEY_CTX) *epc = NULL; openssl_auto(EVP_PKEY) *key = NULL; const EVP_MD *md = NULL; const RSA *rsa = NULL; uint8_t *pt = NULL; uint8_t *ct = NULL; bool ret = false; size_t ptl = 0; size_t ctl = 0; int tmp = 0; int pad = 0; if (!json_object_get(cek, "k") && !jose_jwk_gen(cfg, cek)) return false; switch (str2enum(alg->name, NAMES, NULL)) { case 0: pad = RSA_PKCS1_PADDING; tmp = 11; md = EVP_sha1(); break; case 1: pad = RSA_PKCS1_OAEP_PADDING; tmp = 41; md = EVP_sha1(); break; case 2: pad = RSA_PKCS1_OAEP_PADDING; tmp = 41; md = EVP_sha256(); break; default: return false; } key = jose_openssl_jwk_to_EVP_PKEY(cfg, jwk); if (!key || EVP_PKEY_base_id(key) != EVP_PKEY_RSA) return false; ptl = jose_b64_dec(json_object_get(cek, "k"), NULL, 0); if (ptl == SIZE_MAX) return false; rsa = EVP_PKEY_get0_RSA(key); if (!rsa) return false; if ((int) ptl >= RSA_size(rsa) - tmp) return false; epc = EVP_PKEY_CTX_new(key, NULL); if (!epc) return false; if (EVP_PKEY_encrypt_init(epc) <= 0) return false; if (EVP_PKEY_CTX_set_rsa_padding(epc, pad) <= 0) return false; if (pad == RSA_PKCS1_OAEP_PADDING) { if (EVP_PKEY_CTX_set_rsa_oaep_md(epc, md) <= 0) return false; if (EVP_PKEY_CTX_set_rsa_mgf1_md(epc, md) <= 0) return false; } pt = malloc(ptl); if (!pt) return false; if (jose_b64_dec(json_object_get(cek, "k"), pt, ptl) != ptl) goto egress; if (EVP_PKEY_encrypt(epc, NULL, &ctl, pt, ptl) <= 0) goto egress; ct = malloc(ctl); if (!ct) goto egress; if (EVP_PKEY_encrypt(epc, ct, &ctl, pt, ptl) <= 0) goto egress; if (json_object_set_new(rcp, "encrypted_key", jose_b64_enc(ct, ctl)) < 0) goto egress; ret = add_entity(jwe, rcp, "recipients", "header", "encrypted_key", NULL); egress: if (pt) { OPENSSL_cleanse(pt, ptl); free(pt); } free(ct); return ret; }
/** Encrypt some data. * \param key_count Number of keys in the \a target array. * \param target Array of keys. Anyone who owns any of these keys will be * able to decrypt the data. These keys must include public key data. * \param data Group to encrypt. Will be replaced by an encrypted group. * \return Nonzero iff the operation succeeded. * \sa gale_crypto_target(), gale_crypto_open() */ int gale_crypto_seal( int key_count,const struct gale_group *target, struct gale_group *data) { struct gale_fragment frag; struct gale_data plain,cipher; EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new(); int i,*session_key_length; unsigned char **session_key,iv[EVP_MAX_IV_LENGTH]; struct gale_text *raw_name; EVP_PKEY **public_key; RSA *rsa; int good_count = 0,is_successful = 0; plain.p = gale_malloc(gale_group_size(*data) + gale_u32_size()); plain.l = 0; gale_pack_u32(&plain,0); /* version identifier? */ gale_pack_group(&plain,*data); *data = gale_group_empty(); gale_create_array(raw_name,key_count); gale_create_array(public_key,key_count); for (i = 0; i < key_count; ++i) public_key[i] = NULL; for (i = 0; i < key_count; ++i) { public_key[good_count] = EVP_PKEY_new(); EVP_PKEY_assign_RSA(public_key[good_count],RSA_new()); rsa = EVP_PKEY_get0_RSA(public_key[good_count]); raw_name[good_count] = key_i_swizzle(crypto_i_rsa( target[i],rsa)); if (0 != raw_name[good_count].l && crypto_i_public_valid(rsa)) ++good_count; else EVP_PKEY_free(public_key[good_count]); } gale_create_array(session_key_length,good_count); gale_create_array(session_key,good_count); for (i = 0; i < good_count; ++i) gale_create_array(session_key[i],EVP_PKEY_size(public_key[i])); crypto_i_seed(); if (!EVP_SealInit(context,EVP_des_ede3_cbc(), session_key,session_key_length,iv,public_key,good_count)) { crypto_i_error(); goto cleanup; } cipher.l = gale_copy_size(sizeof(magic2)) + gale_copy_size(EVP_CIPHER_CTX_iv_length(context)) + gale_u32_size() + plain.l + EVP_CIPHER_CTX_block_size(context) - 1; for (i = 0; i < good_count; ++i) cipher.l += gale_text_size(raw_name[i]) + gale_u32_size() + gale_copy_size(session_key_length[i]); cipher.p = gale_malloc(cipher.l); cipher.l = 0; assert(IV_LEN == EVP_CIPHER_CTX_iv_length(context)); gale_pack_copy(&cipher,magic2,sizeof(magic2)); gale_pack_copy(&cipher,iv,IV_LEN); gale_pack_u32(&cipher,good_count); for (i = 0; i < good_count; ++i) { gale_pack_text(&cipher,raw_name[i]); gale_pack_u32(&cipher,session_key_length[i]); gale_pack_copy(&cipher,session_key[i],session_key_length[i]); } EVP_SealUpdate(context,cipher.p + cipher.l,&i,plain.p,plain.l); cipher.l += i; EVP_SealFinal(context,cipher.p + cipher.l,&i); cipher.l += i; frag.type = frag_data; frag.name = G_("security/encryption"); frag.value.data = cipher; gale_group_add(data,frag); is_successful = 1; cleanup: for (i = 0; i < good_count; ++i) if (NULL != public_key[i]) EVP_PKEY_free(public_key[i]); return is_successful; }
int x509_main(int argc, char **argv) { ASN1_INTEGER *sno = NULL; ASN1_OBJECT *objtmp; BIO *out = NULL; CONF *extconf = NULL; EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL; X509 *x = NULL, *xca = NULL; X509_REQ *req = NULL, *rq = NULL; X509_STORE *ctx = NULL; const EVP_MD *digest = NULL; char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL; char *checkhost = NULL, *checkemail = NULL, *checkip = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL; char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL; char buf[256], *prog; int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0; int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM; int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0; int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0; int enddate = 0; time_t checkoffset = 0; unsigned long nmflag = 0, certflag = 0; char nmflag_set = 0; OPTION_CHOICE o; ENGINE *e = NULL; #ifndef OPENSSL_NO_MD5 int subject_hash_old = 0, issuer_hash_old = 0; #endif ctx = X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb(ctx, callb); prog = opt_init(argc, argv, x509_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(x509_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) goto opthelp; break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) goto opthelp; break; case OPT_CAFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat)) goto opthelp; break; case OPT_CAKEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAkeyformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_REQ: reqfile = need_rand = 1; 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_DAYS: days = atoi(opt_arg()); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_EXTFILE: extfile = opt_arg(); break; case OPT_EXTENSIONS: extsect = opt_arg(); break; case OPT_SIGNKEY: keyfile = opt_arg(); sign_flag = ++num; need_rand = 1; break; case OPT_CA: CAfile = opt_arg(); CA_flag = ++num; need_rand = 1; break; case OPT_CAKEY: CAkeyfile = opt_arg(); break; case OPT_CASERIAL: CAserial = opt_arg(); break; case OPT_SET_SERIAL: if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) goto opthelp; break; case OPT_FORCE_PUBKEY: fkeyfile = opt_arg(); break; case OPT_ADDTRUST: if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, "%s: Invalid trust object value %s\n", prog, opt_arg()); goto opthelp; } if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(trust, objtmp); trustout = 1; break; case OPT_ADDREJECT: if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, "%s: Invalid reject object value %s\n", prog, opt_arg()); goto opthelp; } if (reject == NULL && (reject = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(reject, objtmp); trustout = 1; break; case OPT_SETALIAS: alias = opt_arg(); trustout = 1; break; case OPT_CERTOPT: if (!set_cert_ex(&certflag, opt_arg())) goto opthelp; break; case OPT_NAMEOPT: nmflag_set = 1; if (!set_name_ex(&nmflag, opt_arg())) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_C: C = ++num; break; case OPT_EMAIL: email = ++num; break; case OPT_OCSP_URI: ocsp_uri = ++num; break; case OPT_SERIAL: serial = ++num; break; case OPT_NEXT_SERIAL: next_serial = ++num; break; case OPT_MODULUS: modulus = ++num; break; case OPT_PUBKEY: pubkey = ++num; break; case OPT_X509TOREQ: x509req = ++num; break; case OPT_TEXT: text = ++num; break; case OPT_SUBJECT: subject = ++num; break; case OPT_ISSUER: issuer = ++num; break; case OPT_FINGERPRINT: fingerprint = ++num; break; case OPT_HASH: subject_hash = ++num; break; case OPT_ISSUER_HASH: issuer_hash = ++num; break; case OPT_PURPOSE: pprint = ++num; break; case OPT_STARTDATE: startdate = ++num; break; case OPT_ENDDATE: enddate = ++num; break; case OPT_NOOUT: noout = ++num; break; case OPT_NOCERT: nocert = 1; break; case OPT_TRUSTOUT: trustout = 1; break; case OPT_CLRTRUST: clrtrust = ++num; break; case OPT_CLRREJECT: clrreject = ++num; break; case OPT_ALIAS: aliasout = ++num; break; case OPT_CACREATESERIAL: CA_createserial = ++num; break; case OPT_CLREXT: clrext = 1; break; case OPT_OCSPID: ocspid = ++num; break; case OPT_BADSIG: badsig = 1; break; #ifndef OPENSSL_NO_MD5 case OPT_SUBJECT_HASH_OLD: subject_hash_old = ++num; break; case OPT_ISSUER_HASH_OLD: issuer_hash_old = ++num; break; #else case OPT_SUBJECT_HASH_OLD: case OPT_ISSUER_HASH_OLD: break; #endif case OPT_DATES: startdate = ++num; enddate = ++num; break; case OPT_CHECKEND: checkend = 1; { intmax_t temp = 0; if (!opt_imax(opt_arg(), &temp)) goto opthelp; checkoffset = (time_t)temp; if ((intmax_t)checkoffset != temp) { BIO_printf(bio_err, "%s: checkend time out of range %s\n", prog, opt_arg()); goto opthelp; } } break; case OPT_CHECKHOST: checkhost = opt_arg(); break; case OPT_CHECKEMAIL: checkemail = opt_arg(); break; case OPT_CHECKIP: checkip = opt_arg(); break; case OPT_MD: if (!opt_md(opt_unknown(), &digest)) goto opthelp; } } argc = opt_num_rest(); argv = opt_rest(); if (argc != 0) { BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]); goto opthelp; } if (!nmflag_set) nmflag = XN_FLAG_ONELINE; out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (need_rand) app_RAND_load_file(NULL, 0); if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!X509_STORE_set_default_paths(ctx)) { ERR_print_errors(bio_err); goto end; } if (fkeyfile) { fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key"); if (fkey == NULL) goto end; } if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { CAkeyfile = CAfile; } else if ((CA_flag) && (CAkeyfile == NULL)) { BIO_printf(bio_err, "need to specify a CAkey if using the CA command\n"); goto end; } if (extfile) { X509V3_CTX ctx2; if ((extconf = app_load_config(extfile)) == NULL) goto end; if (!extsect) { extsect = NCONF_get_string(extconf, "default", "extensions"); if (!extsect) { ERR_clear_error(); extsect = "default"; } } X509V3_set_ctx_test(&ctx2); X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", extsect); ERR_print_errors(bio_err); goto end; } } if (reqfile) { EVP_PKEY *pkey; BIO *in; if (!sign_flag && !CA_flag) { BIO_printf(bio_err, "We need a private key to sign with\n"); goto end; } in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_free(in); if (req == NULL) { ERR_print_errors(bio_err); goto end; } if ((pkey = X509_REQ_get_pubkey(req)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); goto end; } i = X509_REQ_verify(req, pkey); EVP_PKEY_free(pkey); if (i < 0) { BIO_printf(bio_err, "Signature verification error\n"); ERR_print_errors(bio_err); goto end; } if (i == 0) { BIO_printf(bio_err, "Signature did not match the certificate request\n"); goto end; } else BIO_printf(bio_err, "Signature ok\n"); print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); if ((x = X509_new()) == NULL) goto end; if (sno == NULL) { sno = ASN1_INTEGER_new(); if (sno == NULL || !rand_serial(NULL, sno)) goto end; if (!X509_set_serialNumber(x, sno)) goto end; ASN1_INTEGER_free(sno); sno = NULL; } else if (!X509_set_serialNumber(x, sno)) goto end; if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req))) goto end; if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req))) goto end; X509_gmtime_adj(X509_get_notBefore(x), 0); X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL); if (fkey) X509_set_pubkey(x, fkey); else { pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(x, pkey); EVP_PKEY_free(pkey); } } else x = load_cert(infile, informat, NULL, e, "Certificate"); if (x == NULL) goto end; if (CA_flag) { xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate"); if (xca == NULL) goto end; } if (!noout || text || next_serial) { OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); } if (alias) X509_alias_set1(x, (unsigned char *)alias, -1); if (clrtrust) X509_trust_clear(x); if (clrreject) X509_reject_clear(x); if (trust) { for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { objtmp = sk_ASN1_OBJECT_value(trust, i); X509_add1_trust_object(x, objtmp); } } if (reject) { for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { objtmp = sk_ASN1_OBJECT_value(reject, i); X509_add1_reject_object(x, objtmp); } } if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag); } else if (subject == i) { print_name(out, "subject= ", X509_get_subject_name(x), nmflag); } else if (serial == i) { BIO_printf(out, "serial="); i2a_ASN1_INTEGER(out, X509_get_serialNumber(x)); BIO_printf(out, "\n"); } else if (next_serial == i) { BIGNUM *bnser; ASN1_INTEGER *ser; ser = X509_get_serialNumber(x); bnser = ASN1_INTEGER_to_BN(ser, NULL); if (!bnser) goto end; if (!BN_add_word(bnser, 1)) goto end; ser = BN_to_ASN1_INTEGER(bnser, NULL); if (!ser) goto end; BN_free(bnser); i2a_ASN1_INTEGER(out, ser); ASN1_INTEGER_free(ser); BIO_puts(out, "\n"); } else if ((email == i) || (ocsp_uri == i)) { int j; STACK_OF(OPENSSL_STRING) *emlst; if (email == i) emlst = X509_get1_email(x); else emlst = X509_get1_ocsp(x); for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) BIO_printf(out, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) BIO_printf(out, "%s\n", alstr); else BIO_puts(out, "<No Alias>\n"); } else if (subject_hash == i) { BIO_printf(out, "%08lx\n", X509_subject_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (subject_hash_old == i) { BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x)); } #endif else if (issuer_hash == i) { BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (issuer_hash_old == i) { BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x)); } #endif else if (pprint == i) { X509_PURPOSE *ptmp; int j; BIO_printf(out, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); purpose_print(out, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; pkey = X509_get0_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Modulus=unavailable\n"); ERR_print_errors(bio_err); goto end; } BIO_printf(out, "Modulus="); #ifndef OPENSSL_NO_RSA if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) BN_print(out, EVP_PKEY_get0_RSA(pkey)->n); else #endif #ifndef OPENSSL_NO_DSA if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) BN_print(out, EVP_PKEY_get0_DSA(pkey)->pub_key); else #endif BIO_printf(out, "Wrong Algorithm type"); BIO_printf(out, "\n"); } else if (pubkey == i) { EVP_PKEY *pkey; pkey = X509_get0_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Error getting public key\n"); ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(out, pkey); } else if (C == i) { unsigned char *d; char *m; int len; X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf); BIO_printf(out, "/*\n" " * Subject: %s\n", buf); m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf); BIO_printf(out, " * Issuer: %s\n" " */\n", buf); len = i2d_X509(x, NULL); m = app_malloc(len, "x509 name buffer"); d = (unsigned char *)m; len = i2d_X509_NAME(X509_get_subject_name(x), &d); print_array(out, "the_subject_name", len, (unsigned char *)m); d = (unsigned char *)m; len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); print_array(out, "the_public_key", len, (unsigned char *)m); d = (unsigned char *)m; len = i2d_X509(x, &d); print_array(out, "the_certificate", len, (unsigned char *)m); OPENSSL_free(m); } else if (text == i) { X509_print_ex(out, x, nmflag, certflag); } else if (startdate == i) { BIO_puts(out, "notBefore="); ASN1_TIME_print(out, X509_get_notBefore(x)); BIO_puts(out, "\n"); } else if (enddate == i) { BIO_puts(out, "notAfter="); ASN1_TIME_print(out, X509_get_notAfter(x)); BIO_puts(out, "\n"); } else if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; const EVP_MD *fdig = digest; if (!fdig) fdig = EVP_sha1(); if (!X509_digest(x, fdig, md, &n)) { BIO_printf(bio_err, "out of memory\n"); goto end; } BIO_printf(out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(fdig))); for (j = 0; j < (int)n; j++) { BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } /* should be in the library */ else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err, "Getting Private key\n"); if (Upkey == NULL) { Upkey = load_key(keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; } assert(need_rand); if (!sign(x, Upkey, days, clrext, digest, extconf, extsect)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err, "Getting CA Private Key\n"); if (CAkeyfile != NULL) { CApkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; } assert(need_rand); if (!x509_certify(ctx, CAfile, digest, x, xca, CApkey, sigopts, CAserial, CA_createserial, days, clrext, extconf, extsect, sno, reqfile)) goto end; } else if (x509req == i) { EVP_PKEY *pk; BIO_printf(bio_err, "Getting request Private Key\n"); if (keyfile == NULL) { BIO_printf(bio_err, "no request key file specified\n"); goto end; } else { pk = load_key(keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; } BIO_printf(bio_err, "Generating certificate request\n"); rq = X509_to_X509_REQ(x, pk, digest); EVP_PKEY_free(pk); if (rq == NULL) { ERR_print_errors(bio_err); goto end; } if (!noout) { X509_REQ_print(out, rq); PEM_write_bio_X509_REQ(out, rq); } noout = 1; } else if (ocspid == i) { X509_ocspid_print(out, x); } } } if (checkend) { time_t tcheck = time(NULL) + checkoffset; if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) { BIO_printf(out, "Certificate will expire\n"); ret = 1; } else { BIO_printf(out, "Certificate will not expire\n"); ret = 0; } goto end; } print_cert_checks(out, x, checkhost, checkemail, checkip); if (noout || nocert) { ret = 0; goto end; } if (badsig) { ASN1_BIT_STRING *signature; unsigned char *s; X509_get0_signature(&signature, NULL, x); s = ASN1_STRING_data(signature); s[ASN1_STRING_length(signature) - 1] ^= 0x1; } if (outformat == FORMAT_ASN1) i = i2d_X509_bio(out, x); else if (outformat == FORMAT_PEM) { if (trustout) i = PEM_write_bio_X509_AUX(out, x); else i = PEM_write_bio_X509(out, x); } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write certificate\n"); ERR_print_errors(bio_err); goto end; } ret = 0; end: if (need_rand) app_RAND_write_file(NULL); OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); X509_free(xca); EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); EVP_PKEY_free(fkey); sk_OPENSSL_STRING_free(sigopts); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); OPENSSL_free(passin); return (ret); }
static int certfingerprint(char *file,void *out) { int r=FILEFAIL; int len; BIO *cert; X509 *x509; EVP_PKEY *key; RSA *rsa=NULL; EC_KEY *ec=NULL; unsigned char bfr[2048]; unsigned char *p=bfr; if(!(cert=BIO_new(BIO_s_file())))goto err1; if(BIO_read_filename(cert,file)<=0)goto err2; r=CRYPTOFAIL; if(!(x509=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL)))goto err2; if(!(key=X509_get_pubkey(x509)))goto err3; #if OPENSSL_VERSION_NUMBER >= 0x1010000fL if(EVP_PKEY_get0_RSA(key)) { if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err4; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err5; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err5; } else if(EVP_PKEY_get0_EC_KEY(key)) { if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err4; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err5; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err5; } else goto err4; #else switch(EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err4; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err5; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err5; break; case EVP_PKEY_EC: if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err4; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err5; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err5; break; default:goto err4; } #endif if(out)sha256(bfr,len,out); r=OK; err5: if(rsa)RSA_free(rsa); if(ec)EC_KEY_free(ec); err4: EVP_PKEY_free(key); err3: X509_free(x509); err2: BIO_free(cert); err1: return r; }