/* Allocates new gost_pmeth_data structure and assigns it as data */ static int pkey_gost_init(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); data = OPENSSL_malloc(sizeof(*data)); if (!data) return 0; memset(data, 0, sizeof(*data)); if (pkey && EVP_PKEY_get0(pkey)) { switch (EVP_PKEY_base_id(pkey)) { case NID_id_GostR3410_2001: data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group (EVP_PKEY_get0((EVP_PKEY *)pkey))); break; default: return 0; } } EVP_PKEY_CTX_set_data(ctx, data); return 1; }
/* Allocates new gost_pmeth_data structure and assigns it as data */ static int pkey_gost_init(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); data = (gost_pmeth_data*)OPENSSL_malloc(sizeof(struct gost_pmeth_data)); if (!data) return 0; TINYCLR_SSL_MEMSET(data,0,sizeof(struct gost_pmeth_data)); if (pkey && EVP_PKEY_get0(pkey)) { switch (EVP_PKEY_base_id(pkey)) { case NID_id_GostR3410_94: data->sign_param_nid = gost94_nid_by_params((DSA*)EVP_PKEY_get0(pkey)); break; case NID_id_GostR3410_2001: data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group((const EC_KEY*)EVP_PKEY_get0((EVP_PKEY *)pkey))); break; default: return 0; } } EVP_PKEY_CTX_set_data(ctx,data); return 1; }
static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { case ASN1_PKEY_CTRL_PKCS7_SIGN: if (arg1 == 0) { X509_ALGOR *alg1 = NULL, *alg2 = NULL; int nid = EVP_PKEY_base_id(pkey); PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, NULL, &alg1, &alg2); X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), V_ASN1_NULL, 0); if (nid == NID_undef) { return (-1); } X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); } return 1; case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: if (arg1 == 0) { X509_ALGOR *alg; ASN1_STRING *params = encode_gost_algor_params(pkey); if (!params) { return -1; } PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, params); } return 1; case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = NID_id_GostR3411_94; return 2; } return -2; }
/* --------------------- control functions ------------------------------*/ static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_pmeth_data *pctx = (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx); if (pctx == NULL) return 0; switch (type) { case EVP_PKEY_CTRL_MD: { EVP_PKEY *key = EVP_PKEY_CTX_get0_pkey(ctx); int pkey_nid = (key == NULL) ? NID_undef : EVP_PKEY_base_id(key); OPENSSL_assert(p2 != NULL); switch (EVP_MD_type((const EVP_MD *)p2)) { case NID_id_GostR3411_94: if (pkey_nid == NID_id_GostR3410_2001 || pkey_nid == NID_id_GostR3410_94) { pctx->md = (EVP_MD *)p2; return 1; } break; case NID_id_GostR3411_2012_256: if (pkey_nid == NID_id_GostR3410_2012_256) { pctx->md = (EVP_MD *)p2; return 1; } break; case NID_id_GostR3411_2012_512: if (pkey_nid == NID_id_GostR3410_2012_512) { pctx->md = (EVP_MD *)p2; return 1; } break; } GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); return 0; } case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = pctx->md; return 1; case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: case EVP_PKEY_CTRL_DIGESTINIT: #ifndef OPENSSL_NO_CMS case EVP_PKEY_CTRL_CMS_ENCRYPT: case EVP_PKEY_CTRL_CMS_DECRYPT: case EVP_PKEY_CTRL_CMS_SIGN: #endif return 1; case EVP_PKEY_CTRL_GOST_PARAMSET: pctx->sign_param_nid = (int)p1; return 1; case EVP_PKEY_CTRL_SET_IV: OPENSSL_assert(p2 != NULL); pctx->shared_ukm = OPENSSL_malloc((int)p1); if (pctx->shared_ukm == NULL) { GOSTerr(GOST_F_PKEY_GOST_CTRL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(pctx->shared_ukm, p2, (int)p1); return 1; case EVP_PKEY_CTRL_PEER_KEY: if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ return 1; if (p1 == 2) /* TLS: peer key used? */ return pctx->peer_key_used; if (p1 == 3) /* TLS: peer key used! */ return (pctx->peer_key_used = 1); break; } GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_CTRL_CALL_FAILED); return -2; }
/* * Control function */ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) { int nid = EVP_PKEY_base_id(pkey), md_nid = NID_undef; X509_ALGOR *alg1 = NULL, *alg2 = NULL; switch (nid) { case NID_id_GostR3410_2012_512: md_nid = NID_id_GostR3411_2012_512; break; case NID_id_GostR3410_2012_256: md_nid = NID_id_GostR3411_2012_256; break; case NID_id_GostR3410_2001: case NID_id_GostR3410_94: md_nid = NID_id_GostR3411_94; break; default: return -1; } switch (op) { case ASN1_PKEY_CTRL_PKCS7_SIGN: if (arg1 == 0) { PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, NULL, &alg1, &alg2); X509_ALGOR_set0(alg1, OBJ_nid2obj(md_nid), V_ASN1_NULL, 0); X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); } return 1; #ifndef OPENSSL_NO_CMS case ASN1_PKEY_CTRL_CMS_SIGN: if (arg1 == 0) { CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, NULL, NULL, &alg1, &alg2); X509_ALGOR_set0(alg1, OBJ_nid2obj(md_nid), V_ASN1_NULL, 0); X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); } return 1; #endif case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: if (arg1 == 0) { ASN1_STRING *params = encode_gost_algor_params(pkey); if (!params) { return -1; } PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg1); X509_ALGOR_set0(alg1, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, params); } return 1; #ifndef OPENSSL_NO_CMS case ASN1_PKEY_CTRL_CMS_ENVELOPE: if (arg1 == 0) { ASN1_STRING *params = encode_gost_algor_params(pkey); if (!params) { return -1; } CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, NULL, &alg1); X509_ALGOR_set0(alg1, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, params); } return 1; #endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = md_nid; return 2; } return -2; }
int EVP_PKEY_set_keys(EVP_PKEY *evp_pkey, const unsigned char *privkey, size_t privkey_len, const unsigned char *pubkey, size_t pubkey_len, BN_CTX *bn_ctx) { EC_KEY *ec_key = NULL; DH *dh = NULL; EC_POINT *ec_point = NULL; BIGNUM *bn = NULL, *dh_pub_key, *dh_priv_key; int ok = 0; const EC_GROUP *group; check(evp_pkey, "Invalid arguments"); switch (EVP_PKEY_base_id(evp_pkey)) { case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(evp_pkey); if (!ec_key) goto err; group = EC_KEY_get0_group(ec_key); if (pubkey) { ec_point = EC_POINT_new(group); if (!ec_point || !EC_POINT_oct2point(group, ec_point, pubkey, pubkey_len, bn_ctx) || !EC_KEY_set_public_key(ec_key, ec_point)) goto err; } if (privkey) { bn = BN_bin2bn(privkey, privkey_len, bn); if (!bn || !EC_KEY_set_private_key(ec_key, bn)) goto err; } if (!EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key)) goto err; break; case EVP_PKEY_DH: dh = EVP_PKEY_get1_DH(evp_pkey); if (!dh) goto err; if (pubkey) { dh_pub_key = BN_bin2bn(pubkey, pubkey_len, NULL); if (!dh_pub_key || !DH_set0_key(dh, dh_pub_key, NULL)) goto err; } if (privkey) { dh_priv_key = BN_bin2bn(privkey, privkey_len, NULL); if (!dh_priv_key || !DH_set0_key(dh, NULL, dh_priv_key)) goto err; } if (!EVP_PKEY_set1_DH(evp_pkey, dh)) goto err; break; default: log_err("Unknown type of key"); goto err; break; } ok = 1; err: if (bn) BN_clear_free(bn); if (ec_key) EC_KEY_free(ec_key); if (dh) DH_free(dh); if (ec_point) EC_POINT_clear_free(ec_point); return ok; }
EVP_PKEY * EVP_PKEY_dup(EVP_PKEY *key) { EVP_PKEY *out = NULL; DH *dh_in = NULL, *dh_out = NULL; EC_KEY *ec_in = NULL, *ec_out = NULL; RSA *rsa_in = NULL, *rsa_out = NULL; check(key, "Invalid arguments"); out = EVP_PKEY_new(); if (!out) goto err; switch (EVP_PKEY_base_id(key)) { case EVP_PKEY_DH: dh_in = EVP_PKEY_get1_DH(key); if (!dh_in) goto err; dh_out = DHparams_dup_with_q(dh_in); if (!dh_out) goto err; EVP_PKEY_set1_DH(out, dh_out); DH_free(dh_out); DH_free(dh_in); break; case EVP_PKEY_EC: ec_in = EVP_PKEY_get1_EC_KEY(key); if (!ec_in) goto err; ec_out = EC_KEY_dup(ec_in); if (!ec_out) goto err; EVP_PKEY_set1_EC_KEY(out, ec_out); EC_KEY_free(ec_out); EC_KEY_free(ec_in); break; case EVP_PKEY_RSA: rsa_in = EVP_PKEY_get1_RSA(key); if (!rsa_in) goto err; rsa_out = RSAPrivateKey_dup(rsa_in); if (!rsa_out) goto err; EVP_PKEY_set1_RSA(out, rsa_out); RSA_free(rsa_out); RSA_free(rsa_in); break; default: log_err("Unknown protocol"); goto err; } return out; err: if (dh_in) DH_free(dh_in); if (ec_in) EC_KEY_free(ec_in); if (rsa_in) RSA_free(rsa_in); return NULL; }
BUF_MEM * EAC_sign(int protocol, EVP_PKEY *key, const BUF_MEM *data) { BUF_MEM *signature = NULL, *signature_data = NULL, *plain_sig = NULL; EVP_PKEY_CTX *tmp_key_ctx = NULL; size_t len; const EVP_MD *md = eac_oid2md(protocol); int type; check((key && data), "Invalid arguments"); tmp_key_ctx = EVP_PKEY_CTX_new(key, NULL); if (!tmp_key_ctx || !md || EVP_PKEY_sign_init(tmp_key_ctx) <= 0 || EVP_PKEY_CTX_set_signature_md(tmp_key_ctx, md) <= 0) goto err; type = EVP_PKEY_base_id(key); if ( protocol == NID_id_TA_ECDSA_SHA_1 || protocol == NID_id_TA_ECDSA_SHA_224 || protocol == NID_id_TA_ECDSA_SHA_256 || protocol == NID_id_TA_ECDSA_SHA_384 || protocol == NID_id_TA_ECDSA_SHA_512) { if (!(type == EVP_PKEY_EC)) goto err; } else if (protocol == NID_id_TA_RSA_v1_5_SHA_1 || protocol == NID_id_TA_RSA_v1_5_SHA_256 || protocol == NID_id_TA_RSA_v1_5_SHA_512) { if (!(type == EVP_PKEY_RSA)) goto err; if (!EVP_PKEY_CTX_set_rsa_padding(tmp_key_ctx, RSA_PKCS1_PADDING)) goto err; } else if (protocol == NID_id_TA_RSA_PSS_SHA_1 || protocol == NID_id_TA_RSA_PSS_SHA_256 || protocol == NID_id_TA_RSA_PSS_SHA_512) { if (!(type == EVP_PKEY_RSA)) goto err; if (!EVP_PKEY_CTX_set_rsa_padding(tmp_key_ctx, RSA_PKCS1_PSS_PADDING)) goto err; } else { goto err; } /* EVP_PKEY_sign doesn't perform hashing (despite EVP_PKEY_CTX_set_signature_md). * Therefore we need to compute the hash ourself. */ signature_data = hash(md, NULL, NULL, data); if (!signature_data) goto err; /* Actual signature creation */ if (EVP_PKEY_sign(tmp_key_ctx, NULL, &len, (unsigned char*) signature_data->data, signature_data->length) <= 0) goto err; signature = BUF_MEM_create(len); if (!signature) goto err; if (EVP_PKEY_sign(tmp_key_ctx, (unsigned char *) signature->data, &signature->length, (unsigned char*) signature_data->data, signature_data->length) <= 0) goto err; /* EAC signatures are always in plain signature format for EC curves but * OpenSSL only creates X.509 format. Therefore we need to convert between * these formats. */ if ( protocol == NID_id_TA_ECDSA_SHA_1 || protocol == NID_id_TA_ECDSA_SHA_224 || protocol == NID_id_TA_ECDSA_SHA_256 || protocol == NID_id_TA_ECDSA_SHA_384 || protocol == NID_id_TA_ECDSA_SHA_512) { plain_sig = convert_to_plain_sig(signature); BUF_MEM_free(signature); signature = plain_sig; } err: if (tmp_key_ctx) EVP_PKEY_CTX_free(tmp_key_ctx); if (signature_data) BUF_MEM_free(signature_data); return signature; }
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); }
static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; unsigned char *buf = NULL, *databuf, *sptr; int i, j, data_len, ret = 0; const EC_POINT *pub_key; BIGNUM *X, *Y, *order; const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); if (pk->save_parameters) { ASN1_STRING *params = encode_gost_algor_params(pk); pval = params; ptype = V_ASN1_SEQUENCE; } order = BN_new(); EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); pub_key = EC_KEY_get0_public_key(ec); if (!pub_key) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); BN_free(order); return 0; } X = BN_new(); Y = BN_new(); if(!X || !Y) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); if(X) BN_free(X); if(Y) BN_free(Y); BN_free(order); return 0; } if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), pub_key, X, Y, NULL)) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); BN_free(X); BN_free(Y); BN_free(order); return 0; } data_len = 2 * BN_num_bytes(order); BN_free(order); databuf = OPENSSL_malloc(data_len); if (databuf == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); BN_free(X); BN_free(Y); return 0; } memset(databuf, 0, data_len); store_bignum(X, databuf + data_len / 2, data_len / 2); store_bignum(Y, databuf, data_len / 2); BN_free(X); BN_free(Y); octet = ASN1_OCTET_STRING_new(); if (octet == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); OPENSSL_free(databuf); return 0; } ASN1_STRING_set(octet, NULL, data_len); sptr = ASN1_STRING_data(octet); for (i = 0, j = data_len - 1; i < data_len; i++, j--) { sptr[i] = databuf[j]; } OPENSSL_free(databuf); ret = i2d_ASN1_OCTET_STRING(octet, &buf); ASN1_BIT_STRING_free(octet); if (ret < 0) return 0; return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); }
static void CheckPublicKey(X509 *x509, struct tm tm_after) { EVP_PKEY *pkey = X509_get_pubkey(x509); if (pkey == NULL) { SetError(ERR_UNKNOWN_PUBLIC_KEY_TYPE); } else if (EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA) { RSA *rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) { SetError(ERR_INVALID); RSA_free(rsa); return; } const BIGNUM *n, *e; RSA_get0_key(rsa, &n, &e, NULL); if (n == NULL || e == NULL) { SetError(ERR_INVALID); RSA_free(rsa); return; } if (!GetBit(errors, ERR_INVALID_TIME_FORMAT)) { if (tm_after.tm_year >= 114 && BN_num_bits(n) < 2048) { SetError(ERR_RSA_SIZE_2048); } } if (BN_is_odd(e) == 0) { SetError(ERR_RSA_EXP_NOT_ODD); } BIGNUM *i = BN_new(); BN_set_word(i, 3); if (BN_cmp(e, i) < 0) { SetError(ERR_RSA_EXP_3); } else { BN_set_word(i, 0x10001); if (BN_cmp(e, i) < 0) { SetWarning(WARN_RSA_EXP_RANGE); } BN_hex2bn(&i, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); if (BN_cmp(e, i) > 0) { SetWarning(WARN_RSA_EXP_RANGE); } } BN_CTX *ctx = BN_CTX_new(); if (BN_gcd(i, n, bn_factors, ctx) == 0 || !BN_is_one(i)) { SetError(ERR_RSA_SMALL_FACTOR); } BN_free(i); BN_CTX_free(ctx); RSA_free(rsa); } else if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) { EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pkey); const EC_GROUP *group = EC_KEY_get0_group(ec_key); const EC_POINT *point = EC_KEY_get0_public_key(ec_key); BN_CTX *ctx = BN_CTX_new(); BIGNUM *order = BN_new(); EC_GROUP_get_order(group, order, ctx); if (EC_POINT_is_at_infinity(group, point)) { SetError(ERR_EC_AT_INFINITY); } if (EC_POINT_is_on_curve(group, point, ctx) != 1) { SetError(ERR_EC_POINT_NOT_ON_CURVE); } EC_POINT *result = EC_POINT_new(group); if (BN_is_zero(order)) { SetError(ERR_EC_INVALID_GROUP_ORDER); } EC_POINT_mul(group, result, NULL, point, order, ctx); if (!EC_POINT_is_at_infinity(group, result)) { SetError(ERR_EC_INCORRECT_ORDER); } int nid = EC_GROUP_get_curve_name(group); if (nid != NID_X9_62_prime256v1 && nid != NID_secp384r1 && nid != NID_secp521r1) { SetError(ERR_EC_NON_ALLOWED_CURVE); } EC_POINT_free(result); BN_free(order); BN_CTX_free(ctx); EC_KEY_free(ec_key); } else { SetError(ERR_UNKNOWN_PUBLIC_KEY_TYPE); } if (pkey != NULL) { EVP_PKEY_free(pkey); } }
int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ) { GOST_KEY_TRANSPORT *gkt=NULL; unsigned char shared_key[32], ukm[8],crypted_key[44]; const struct gost_cipher_info *param=get_encryption_params(NULL); EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx); struct gost_pmeth_data *data = (gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); gost_ctx cctx; int key_is_ephemeral=1; EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx); /* Do not use vizir cipher parameters with cryptopro */ if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list) { param= gost_cipher_list+1; } if (mykey) { /* If key already set, it is not ephemeral */ key_is_ephemeral=0; if (!gost_get0_priv_key(mykey)) { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); goto err; } } else { /* Otherwise generate ephemeral key */ key_is_ephemeral = 1; if (out) { mykey = EVP_PKEY_new(); EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk),DSA_new()); EVP_PKEY_copy_parameters(mykey,pubk); if (!gost_sign_keygen((DSA*)EVP_PKEY_get0(mykey))) { goto err; } } } if (out) make_cp_exchange_key(gost_get0_priv_key(mykey),pubk,shared_key); if (data->shared_ukm) { TINYCLR_SSL_MEMCPY(ukm,data->shared_ukm,8); } else if (out) { if (RAND_bytes(ukm,8)<=0) { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_RANDOM_GENERATOR_FAILURE); goto err; } } if (out) { gost_init(&cctx,param->sblock); keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key); } gkt = GOST_KEY_TRANSPORT_new(); if (!gkt) { goto memerr; } if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm,8)) { goto memerr; } if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) { goto memerr; } if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) { goto memerr; } if (key_is_ephemeral) { if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?mykey:pubk)) { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY); goto err; } if (out) EVP_PKEY_free(mykey); } ASN1_OBJECT_free(gkt->key_agreement_info->cipher); gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); *outlen = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL); if (*outlen == 0) { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO); goto err; } if (!key_is_ephemeral) { /* Set control "public key from client certificate used" */ if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); goto err; } } GOST_KEY_TRANSPORT_free(gkt); return 1; memerr: if (key_is_ephemeral) { EVP_PKEY_free(mykey); } GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_MALLOC_FAILURE); err: GOST_KEY_TRANSPORT_free(gkt); return -1; }
/** * @retval 1 equal * @retval 0 not equal * @retval -1 error */ static int CompareCertToRSA(X509 *cert, RSA *rsa_key) { int ret; int retval = -1; /* ERROR */ EVP_PKEY *cert_pkey = X509_get_pubkey(cert); if (cert_pkey == NULL) { Log(LOG_LEVEL_ERR, "X509_get_pubkey: %s", TLSErrorString(ERR_get_error())); goto ret1; } if (EVP_PKEY_base_id(cert_pkey) != EVP_PKEY_RSA) { Log(LOG_LEVEL_ERR, "Received key of unknown type, only RSA currently supported!"); goto ret2; } RSA *cert_rsa_key = EVP_PKEY_get1_RSA(cert_pkey); if (cert_rsa_key == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_get1_RSA failed!"); goto ret2; } EVP_PKEY *rsa_pkey = EVP_PKEY_new(); if (rsa_pkey == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_new allocation failed!"); goto ret3; } ret = EVP_PKEY_set1_RSA(rsa_pkey, rsa_key); if (ret == 0) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_set1_RSA failed!"); goto ret4; } ret = EVP_PKEY_cmp(cert_pkey, rsa_pkey); if (ret == 1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare equal"); retval = 1; /* EQUAL */ } else if (ret == 0 || ret == -1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare different"); retval = 0; /* NOT EQUAL */ } else { Log(LOG_LEVEL_ERR, "OpenSSL EVP_PKEY_cmp: %d %s", ret, TLSErrorString(ERR_get_error())); } ret4: EVP_PKEY_free(rsa_pkey); ret3: RSA_free(cert_rsa_key); ret2: EVP_PKEY_free(cert_pkey); ret1: return retval; }
static bool alg_wrap_unw(const jose_hook_alg_t *alg, jose_cfg_t *cfg, const json_t *jwe, const json_t *rcp, const json_t *jwk, json_t *cek) { openssl_auto(EVP_PKEY_CTX) *epc = NULL; openssl_auto(EVP_PKEY) *key = NULL; const uint8_t *tt = NULL; const EVP_MD *md = NULL; uint8_t *ct = NULL; uint8_t *pt = NULL; uint8_t *rt = NULL; bool ret = false; size_t ctl = 0; size_t ptl = 0; size_t rtl = 0; size_t ttl = 0; int pad = 0; switch (str2enum(alg->name, NAMES, NULL)) { case 0: pad = RSA_PKCS1_PADDING; md = EVP_sha1(); break; case 1: pad = RSA_PKCS1_OAEP_PADDING; md = EVP_sha1(); break; case 2: pad = RSA_PKCS1_OAEP_PADDING; 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) goto egress; ctl = jose_b64_dec(json_object_get(rcp, "encrypted_key"), NULL, 0); if (ctl == SIZE_MAX) goto egress; ct = malloc(ctl); if (!ct) goto egress; if (jose_b64_dec(json_object_get(rcp, "encrypted_key"), ct, ctl) != ctl) goto egress; ptl = ctl; pt = malloc(ptl); if (!pt) goto egress; epc = EVP_PKEY_CTX_new(key, NULL); if (!epc) goto egress; if (EVP_PKEY_decrypt_init(epc) <= 0) goto egress; if (EVP_PKEY_CTX_set_rsa_padding(epc, pad) <= 0) goto egress; 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) goto egress; } /* Handle MMA Attack as prescribed by RFC 3218, always generate a * random buffer of appropriate length so that the same operations * are performed whether decrypt succeeds or not, in an attempt to * foil timing attacks */ rtl = ptl; rt = malloc(rtl); if (!rt) goto egress; if (RAND_bytes(rt, rtl) <= 0) goto egress; ret |= EVP_PKEY_decrypt(epc, pt, &ptl, ct, ctl) > 0; ttl = ret ? ptl : rtl; tt = ret ? pt : rt; ret |= pad == RSA_PKCS1_PADDING; if (json_object_set_new(cek, "k", jose_b64_enc(tt, ttl)) < 0) ret = false; egress: if (pt) { OPENSSL_cleanse(pt, ptl); free(pt); } if (rt) { OPENSSL_cleanse(rt, rtl); free(rt); } free(ct); return ret; }
int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key, size_t key_len) { GOST_KEY_TRANSPORT *gkt = NULL; EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); const struct gost_cipher_info *param = get_encryption_params(NULL); unsigned char ukm[8], shared_key[32], crypted_key[44]; int ret = 0; int key_is_ephemeral = 1; gost_ctx cctx; EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); if (data->shared_ukm) { memcpy(ukm, data->shared_ukm, 8); } else if (out) { if (RAND_bytes(ukm, 8) <= 0) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_RANDOM_GENERATOR_FAILURE); return 0; } } /* Check for private key in the peer_key of context */ if (sec_key) { key_is_ephemeral = 0; if (!gost_get0_priv_key(sec_key)) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); goto err; } } else { key_is_ephemeral = 1; if (out) { sec_key = EVP_PKEY_new(); EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new()); EVP_PKEY_copy_parameters(sec_key, pubk); if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) { goto err; } } } if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list) { param = gost_cipher_list + 1; } if (out) { VKO_compute_key(shared_key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)), EVP_PKEY_get0(sec_key), ukm); gost_init(&cctx, param->sblock); keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key); } gkt = GOST_KEY_TRANSPORT_new(); if (!gkt) { goto err; } if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { goto err; } if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { goto err; } if (!ASN1_OCTET_STRING_set (gkt->key_info->encrypted_key, crypted_key + 8, 32)) { goto err; } if (key_is_ephemeral) { if (!X509_PUBKEY_set (&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk)) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CANNOT_PACK_EPHEMERAL_KEY); goto err; } } ASN1_OBJECT_free(gkt->key_agreement_info->cipher); gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); if (key_is_ephemeral) EVP_PKEY_free(sec_key); if (!key_is_ephemeral) { /* Set control "public key from client certificate used" */ if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); goto err; } } if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0) ret = 1; GOST_KEY_TRANSPORT_free(gkt); return ret; err: if (key_is_ephemeral) EVP_PKEY_free(sec_key); GOST_KEY_TRANSPORT_free(gkt); return -1; }
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; }
void Families::LoadCertificate (const std::string& filename) { SSL_CTX * ctx = SSL_CTX_new (TLS_method ()); int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM); if (ret) { SSL * ssl = SSL_new (ctx); X509 * cert = SSL_get_certificate (ssl); if (cert) { std::shared_ptr<i2p::crypto::Verifier> verifier; // extract issuer name char name[100]; X509_NAME_oneline (X509_get_issuer_name(cert), name, 100); char * cn = strstr (name, "CN="); if (cn) { cn += 3; char * family = strstr (cn, ".family"); if (family) family[0] = 0; } auto pkey = X509_get_pubkey (cert); int keyType = EVP_PKEY_base_id (pkey); switch (keyType) { case EVP_PKEY_DSA: // TODO: break; case EVP_PKEY_EC: { EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey); if (ecKey) { auto group = EC_KEY_get0_group (ecKey); if (group) { int curve = EC_GROUP_get_curve_name (group); if (curve == NID_X9_62_prime256v1) { uint8_t signingKey[64]; BIGNUM * x = BN_new(), * y = BN_new(); EC_POINT_get_affine_coordinates_GFp (group, EC_KEY_get0_public_key (ecKey), x, y, NULL); i2p::crypto::bn2buf (x, signingKey, 32); i2p::crypto::bn2buf (y, signingKey + 32, 32); BN_free (x); BN_free (y); verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>(); verifier->SetPublicKey (signingKey); } else LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); } EC_KEY_free (ecKey); } break; } default: LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported"); } EVP_PKEY_free (pkey); if (verifier && cn) m_SigningKeys[cn] = verifier; } SSL_free (ssl); } else LogPrint (eLogError, "Family: Can't open certificate file ", filename); SSL_CTX_free (ctx); }
/* * Store private key */ static int pkcs11_store_key(PKCS11_TOKEN *token, EVP_PKEY *pk, unsigned int type, char *label, unsigned char *id, size_t id_len, PKCS11_KEY ** ret_key) { PKCS11_SLOT *slot = TOKEN2SLOT(token); PKCS11_CTX *ctx = TOKEN2CTX(token); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); CK_OBJECT_HANDLE object; CK_ATTRIBUTE attrs[32]; unsigned int n = 0; int rv; const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_p, *rsa_q; /* First, make sure we have a session */ if (!spriv->haveSession && PKCS11_open_session(slot, 1)) return -1; /* Now build the key attrs */ pkcs11_addattr_int(attrs + n++, CKA_CLASS, type); if (label) pkcs11_addattr_s(attrs + n++, CKA_LABEL, label); if (id && id_len) pkcs11_addattr(attrs + n++, CKA_ID, id, id_len); pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bool(attrs + n++, CKA_PRIVATE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SENSITIVE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_DECRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SIGN, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_UNWRAP, TRUE); } else { /* CKO_PUBLIC_KEY */ pkcs11_addattr_bool(attrs + n++, CKA_ENCRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_VERIFY, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_WRAP, TRUE); } #if OPENSSL_VERSION_NUMBER >= 0x10100003L if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA) { RSA *rsa = EVP_PKEY_get1_RSA(pk); #else if (pk->type == EVP_PKEY_RSA) { RSA *rsa = pk->pkey.rsa; #endif pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA); #if OPENSSL_VERSION_NUMBER >= 0x10100005L RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); RSA_get0_factors(rsa, &rsa_p, &rsa_q); #else rsa_n=rsa->n; rsa_e=rsa->e; rsa_d=rsa->d; rsa_p=rsa->p; rsa_q=rsa->q; #endif pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa_n); pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa_e); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bn(attrs + n++, CKA_PRIVATE_EXPONENT, rsa_d); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_1, rsa_p); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_2, rsa_q); } } else { pkcs11_zap_attrs(attrs, n); PKCS11err(type == CKO_PRIVATE_KEY ? PKCS11_F_PKCS11_STORE_PRIVATE_KEY : PKCS11_F_PKCS11_STORE_PUBLIC_KEY, PKCS11_NOT_SUPPORTED); return -1; } /* Now call the pkcs11 module to create the object */ rv = CRYPTOKI_call(ctx, C_CreateObject(spriv->session, attrs, n, &object)); /* Zap all memory allocated when building the template */ pkcs11_zap_attrs(attrs, n); CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, rv); /* Gobble the key object */ return pkcs11_init_key(ctx, token, spriv->session, object, type, ret_key); } /* * Get the key type */ int pkcs11_get_key_type(PKCS11_KEY *key) { PKCS11_KEY_private *kpriv = PRIVKEY(key); return kpriv->ops->type; }
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); }