Commit 6355d315 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add function PKCS8_set0_pbe



This adds a new function which will encrypt a private key using PKCS#8
based on an X509_ALGOR structure and reimplements PKCS8_encrypt to use it.

Update pkcs8 utlity to use PKCS8_set0_pbe.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent fef034f8
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -226,18 +226,30 @@ int pkcs8_main(int argc, char **argv)
                goto end;
            }
        } else {
            X509_ALGOR *pbe;
            if (cipher)
                pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, pbe_nid);
            else
                pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0);
            if (pbe == NULL) {
                BIO_printf(bio_err, "Error setting PBE algorithm\n");
                ERR_print_errors(bio_err);
                goto end;
            }
            if (passout)
                p8pass = passout;
            else {
                p8pass = pass;
                if (EVP_read_pw_string
                    (pass, sizeof pass, "Enter Encryption Password:", 1))
                    (pass, sizeof pass, "Enter Encryption Password:", 1)) {
                    X509_ALGOR_free(pbe);
                    goto end;
                }
            }
            app_RAND_load_file(NULL, 0);
            if ((p8 = PKCS8_encrypt(pbe_nid, cipher,
                                    p8pass, strlen(p8pass),
                                    NULL, 0, iter, p8inf)) == NULL) {
            p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe);
            if (p8 == NULL) {
                X509_ALGOR_free(pbe);
                BIO_printf(bio_err, "Error encrypting key\n");
                ERR_print_errors(bio_err);
                goto end;
+31 −18
Original line number Diff line number Diff line
@@ -66,14 +66,9 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
                        unsigned char *salt, int saltlen, int iter,
                        PKCS8_PRIV_KEY_INFO *p8inf)
{
    X509_SIG *p8;
    X509_SIG *p8 = NULL;
    X509_ALGOR *pbe;

    if ((p8 = X509_SIG_new()) == NULL) {
        PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (pbe_nid == -1)
        pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
    else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
@@ -84,22 +79,40 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
    }
    if (!pbe) {
        PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
        goto err;
        return NULL;
    }
    X509_ALGOR_free(p8->algor);
    p8->algor = pbe;
    ASN1_OCTET_STRING_free(p8->digest);
    p8->digest =
        PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
                                pass, passlen, p8inf, 1);
    if (!p8->digest) {
        PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
        goto err;
    p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe);
    if (p8 == NULL) {
        X509_ALGOR_free(pbe);
        return NULL;
    }

    return p8;
}

 err:
    X509_SIG_free(p8);
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
                         PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
{
    X509_SIG *p8;
    ASN1_OCTET_STRING *enckey;

    enckey =
        PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
                                pass, passlen, p8inf, 1);
    if (!enckey) {
        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR);
        return NULL;
    }

    if (!(p8 = X509_SIG_new())) {
        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, ERR_R_MALLOC_FAILURE);
        ASN1_OCTET_STRING_free(enckey);
        return NULL;
    }
    X509_ALGOR_free(p8->algor);
    ASN1_OCTET_STRING_free(p8->digest);
    p8->algor = pbe;
    p8->digest = enckey;

    return p8;
}
+2 −1
Original line number Diff line number Diff line
/* crypto/pkcs12/pk12err.c */
/* ====================================================================
 * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
 * Copyright (c) 1999-2015 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
@@ -101,6 +101,7 @@ static ERR_STRING_DATA PKCS12_str_functs[] = {
    {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"},
    {ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"},
    {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"},
    {ERR_FUNC(PKCS12_F_PKCS8_SET0_PBE), "PKCS8_set0_pbe"},
    {0, NULL}
};

+3 −0
Original line number Diff line number Diff line
@@ -182,6 +182,8 @@ PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
                        const char *pass, int passlen, unsigned char *salt,
                        int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
                        PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe);
PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
                                     int passlen, unsigned char *salt,
                                     int saltlen, int iter,
@@ -309,6 +311,7 @@ void ERR_load_PKCS12_strings(void);
# define PKCS12_F_PKCS12_VERIFY_MAC                       126
# define PKCS12_F_PKCS8_ADD_KEYUSAGE                      124
# define PKCS12_F_PKCS8_ENCRYPT                           125
# define PKCS12_F_PKCS8_SET0_PBE                          132

/* Reason codes. */
# define PKCS12_R_CANT_PACK_STRUCTURE                     100