Probable bug causes SEGFAULT due to access to pointers in
uninitialized EVP_CIPHER_CTX structure given to EVP_CipherInit_ex
function by PKCS5_pbe2_set function, when using PEM_write_PKCS8PrivateKey
function to save encrypted private key into file like this:

FILE *f;
EVP_PKEY *pkey;

/* initialisation of f and pkey... */

...

PEM_write_PKCS8PrivateKey(f, pkey, EVP_des_ede3_cbc(),
                          "blaah", 5, NULL, NULL);

Debug log
-------------------------------------------------------
Breakpoint 2, PEM_write_PKCS8PrivateKey (fp=0x414bae94, x=0x414acfe8,
    enc=0x8129980, kstr=0x414a8ff8 "blaah", klen=5, cb=0, u=0x0)
    at pem_pk8.c:208
208             return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb,
u);
(gdb) p enc
$1 = (EVP_CIPHER *) 0x8129980
(gdb) p *enc
$2 = {nid = 44, block_size = 8, key_len = 24, iv_len = 8, flags = 2,
  init = 0x808fb10 <des_ede3_init_key>,
  do_cipher = 0x808f830 <des_ede_cbc_cipher>, cleanup = 0, ctx_size = 384,
  set_asn1_parameters = 0x8092780 <EVP_CIPHER_set_asn1_iv>,
  get_asn1_parameters = 0x80926e0 <EVP_CIPHER_get_asn1_iv>, ctrl = 0,
  app_data = 0x0}
(gdb) p *x
$3 = {type = 6, save_type = 6, references = 1, pkey = {ptr = 0x414b4fac
"",
    rsa = 0x414b4fac, dsa = 0x414b4fac, dh = 0x414b4fac}, save_parameters
= 1,
  attributes = 0x0}
(gdb) c
Continuing.

Breakpoint 1, PKCS5_pbe2_set (cipher=0x8129980, iter=0, salt=0x0,
saltlen=0)
    at p5_pbev2.c:90
90              X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
(gdb) n
94              PBKDF2PARAM *kdf = NULL;
(gdb) n
95              PBE2PARAM *pbe2 = NULL;
(gdb) n
96              ASN1_OCTET_STRING *osalt = NULL;
(gdb) p *cipher
$4 = {nid = 44, block_size = 8, key_len = 24, iv_len = 8, flags = 2,
  init = 0x808fb10 <des_ede3_init_key>,
  do_cipher = 0x808f830 <des_ede_cbc_cipher>, cleanup = 0, ctx_size = 384,
  set_asn1_parameters = 0x8092780 <EVP_CIPHER_set_asn1_iv>,
  get_asn1_parameters = 0x80926e0 <EVP_CIPHER_get_asn1_iv>, ctrl = 0,
  app_data = 0x0}
(gdb) n
99              alg_nid = EVP_CIPHER_type(cipher);
(gdb) n
100             if(alg_nid == NID_undef) {
(gdb) n
105             obj = OBJ_nid2obj(alg_nid);
(gdb) n
107             if(!(pbe2 = PBE2PARAM_new())) goto merr;
(gdb) n
110             scheme = pbe2->encryption;
(gdb) n
112             scheme->algorithm = obj;
(gdb) n
113             if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
(gdb) n
116             if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) <
0)
(gdb) n
120             EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
(gdb) s
EVP_CipherInit_ex (ctx=0x415ea7e4, cipher=0x8129980, impl=0x0, key=0x0,
    iv=0x415ea7d4 "<EB><C2><A2><DE><C0>\035h%\004<A8>^A\023", enc=0) at
evp_enc.c:88
88              if (enc == -1)
(gdb) p *ctx
$5 = {cipher = 0x2, engine = 0x414e0ffc, encrypt = 0, buf_len = 0,
  oiv = "\0\0\0\0\0\0\0\0\210<A4>\022\b0<A8>^A",
  iv = "\225|\t\b\\<A8>^A\210<A4>\022\b\0\0\0",
  buf =
"||\t\b\0\n\023\b<B6>\0\0\0<D0>\001\0\0\024\0\0\0\b\0\0\0l\002\0\0`<A8>^A",
  num = 134839370, app_data = 0x415ea85c, key_len = 135439496, flags = 0,
  cipher_data = 0x8097c2c, final_used = 135465472, block_mask = 1,
  final =
"\020\0\0\0<AC><CF>\t\b<F0><CF>MA<F8>\017NA\220<A8>^AT^\t\b\210<A4>\022\b`\002\0"}
(gdb) n
92                      if (enc)
(gdb) n
94                      ctx->encrypt = enc;
(gdb) n
100             if (ctx->engine && ctx->cipher && (!cipher ||
(gdb) l
95                      }
96              /* Whether it's nice or not, "Inits" can be used on
"Final"'d contexts
97               * so this context may already have an ENGINE! Try to
avoid releasing
98               * the previous handle, re-querying for an ENGINE, and
having a
99               * reinitialisation, when it may all be unecessary. */
100             if (ctx->engine && ctx->cipher && (!cipher ||
101                             (cipher && (cipher->nid ==
ctx->cipher->nid))))
102                     goto skip_to_init;
103             if (cipher)
104                     {
(gdb) p *ctx
$6 = {cipher = 0x2, engine = 0x414e0ffc, encrypt = 0, buf_len = 0,
  oiv = "\0\0\0\0\0\0\0\0\210<A4>\022\b0<A8>^A",
  iv = "\225|\t\b\\<A8>^A\210<A4>\022\b\0\0\0",
  buf =
"||\t\b\0\n\023\b<B6>\0\0\0<D0>\001\0\0\024\0\0\0\b\0\0\0l\002\0\0`<A8>^A",
  num = 134839370, app_data = 0x415ea85c, key_len = 135439496, flags = 0,
  cipher_data = 0x8097c2c, final_used = 135465472, block_mask = 1,
  final =
"\020\0\0\0<AC><CF>\t\b<F0><CF>MA<F8>\017NA\220<A8>^AT^\t\b\210<A4>\022\b`\002\0"}
(gdb) p cipher
$7 = (EVP_CIPHER *) 0x8129980
(gdb) p ctx->cipher
$8 = (EVP_CIPHER *) 0x2
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x0808e1d2 in EVP_CipherInit_ex (ctx=0x415ea7e4, cipher=0x8129980,
impl=0x0,
    key=0x0, iv=0x415ea7d4 "<EB><C2><A2><DE><C0>\035h%\004<A8>^A\023",
enc=0) at evp_enc.c:100
100             if (ctx->engine && ctx->cipher && (!cipher ||
(gdb) bt
#0  0x0808e1d2 in EVP_CipherInit_ex (ctx=0x415ea7e4, cipher=0x8129980,
    impl=0x0, key=0x0, iv=0x415ea7d4 "<EB><C2><A2><DE><C0>\035h%\004<A8>^A\023", enc=0)
    at evp_enc.c:100
#1  0x0809ea84 in PKCS5_pbe2_set (cipher=0x8129980, iter=0, salt=0x0,
    saltlen=0) at p5_pbev2.c:120
#2  0x080b1eeb in PKCS8_encrypt (pbe_nid=-1, cipher=0x8129980,
    pass=0x414a8ff8 "blaah", passlen=5, salt=0x0, saltlen=0, iter=0,
    p8inf=0x414c4fec) at p12_p8e.c:76
#3  0x080a04a8 in do_pk8pkey (bp=0x414c2fc0, x=0x414acfe8, isder=0,
nid=-1,
    enc=0x8129980, kstr=0x414a8ff8 "blaah", klen=5, cb=0, u=0x0)
    at pem_pk8.c:138
#4  0x080a08de in do_pk8pkey_fp (fp=0x414bae94, x=0x414acfe8, isder=0,
nid=-1,
    enc=0x8129980, kstr=0x414a8ff8 "blaah", klen=5, cb=0, u=0x0)
    at pem_pk8.c:221
#5  0x080a084b in PEM_write_PKCS8PrivateKey (fp=0x414bae94, x=0x414acfe8,
    enc=0x8129980, kstr=0x414a8ff8 "blaah", klen=5, cb=0, u=0x0)
    at pem_pk8.c:208
#6  0x0804fba6 in gen_privkey (boss=0x41106fb8) at privkey.c:27
#7  0x08054179 in _st_thread_main () at sched.c:621
-------------------------------------------------------


Code that triggered this:
-------------------------------------------------------
void *gen_privkey(void *boss)
{
    STACK* centres;
    AS_CentreData *centre;
    EVP_PKEY *pkey, *pub = NULL;
    RSA *rsa = NULL;
    FILE *f;
    char *pass;
    int i, j, state, *doing_genkey;
    const EVP_CIPHER *cipher;

    cipher = EVP_des_ede3_cbc();

    doing_genkey = boss_genkey_data(boss, &pass);
fprintf(stderr, "parool on '%s'\n", pass);
    if (!(pkey = EVP_PKEY_new()) ||
      !(pub = EVP_PKEY_new()) ||
      !(rsa = RSA_generate_key(1024, 0x10001, RSA_genkey_cb, NULL)) ||
      !EVP_PKEY_assign_RSA(pkey, rsa) ||
      !(rsa = RSAPublicKey_dup(rsa)) ||
      !EVP_PKEY_assign_RSA(pub, rsa) || (rsa = NULL) ||
      open_file(&f, "temp_proxy_key.pem", "wb") ||
/* SEGFAULT happens in EVP_CipherInit_ex, when pass != NULL */
      !close_file(f, PEM_write_PKCS8PrivateKey(f, pkey,
           pass ? cipher : NULL, pass, pass ? strlen(pass) : 0, NULL,
NULL) &&
           PEM_write_PUBKEY(f, pub)) ||
      rename_file("temp_proxy_key.pem", "proxy_key.pem")) {

        EVP_PKEY_free(pkey);
        EVP_PKEY_free(pub);
        RSA_free(rsa);
        boss_estack(boss, PROXY_ERR_CREATE_PRIVATE_KEY,
                    "create private key failed");
    } else {
-------------------------------------------------------


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to