Ejemplo n.º 1
0
/* 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;
	}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
/* --------------------- 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;
}
Ejemplo n.º 5
0
/*
 * 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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
0
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;
	}
Ejemplo n.º 13
0
/**
 * @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;
}
Ejemplo n.º 14
0
Archivo: rsaes.c Proyecto: simo5/jose
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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
Archivo: rsaes.c Proyecto: simo5/jose
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;
}
Ejemplo n.º 17
0
	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);
	}
Ejemplo n.º 18
0
/*
 * 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;
}
Ejemplo n.º 19
0
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);
}