Hello
When using OpenSSL-1.0.1e-fips a call to PEM_write_bio_PrivateKey
silently fails and produces a corrupt pem file when using an
EVP_PKEY_EC key and a binary curve. The same function works fine when
not using a FIPS capable OpenSSL. I suspect the same problem will
affect any ASN.1 routines that attempt to write the private key.
Please see attached:
* A test case c file that demonstrates the problem
* Two example corrupt pem files
* A patch to rectify the problem
The patch has been tested against OpenSSL-1.0.1e and corrects the following:
* Modifies eckey_param2type in ec_ameth.c to check for a 0 return from
i2d_ECParameters to prevent a silent failure
* Modifies the checks to see if the functions should have been called
in EC_GROUP_get_trinomial_basis and EC_GROUP_get_pentanomial_basis
within ec_asn1.c, so that they work in FIPS mode
Please can someone apply this patch, as binary curves are currently
broken in FIPS mode.
Thanks
Matt
#include
#include
#include
#include
EVP_PKEY *generate_key(int curve);
int main(int arc, char *argv[])
{
EVP_PKEY *key;
int i;
/* Initialise the library */
ERR_load_crypto_strings();
/* Generate an Elliptic Curve key (for ECDSA) */
for(i=0; i<2; i++)
{
key = generate_key(i==0?NID_sect233k1:NID_sect131r1);
if(key == NULL)
{
printf("Error generating key\n");
goto err;
}
BIO *bp;
char filename[80];
sprintf(filename, "out%d.pem", i);
if(NULL == (bp = BIO_new_file(filename, "wb"))) goto err;
if (1 != PEM_write_bio_PrivateKey(bp, key, NULL, NULL, 0, 0, NULL)) goto err;
BIO_free(bp);
EVP_PKEY_free(key);
}
printf("Finished\n");
goto finish;
/* Clean up */
err:
ERR_print_errors_fp(stderr);
finish:
ERR_free_strings();
}
EVP_PKEY *generate_key(int curve)
{
EVP_PKEY_CTX *pctx = NULL, *kctx = NULL;
EVP_PKEY *params = NULL, *key = NULL;
/* Create the context for generating the parameters */
if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) goto err;
if(!EVP_PKEY_paramgen_init(pctx)) goto err;
/*if(!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sect233k1)) goto err;*/
if(!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sect131r1)) goto err;
/* Generate parameters */
if (!EVP_PKEY_paramgen(pctx, ¶ms)) goto err;
/* Create context for the key generation */
if(!(kctx = EVP_PKEY_CTX_new(params, NULL))) goto err;
/* Generate the key */
if(!EVP_PKEY_keygen_init(kctx)) goto err;
if (!EVP_PKEY_keygen(kctx, &key)) goto err;
goto finish;
err:
ERR_print_errors_fp(stderr);
finish:
if(pctx) EVP_PKEY_CTX_free(pctx);
if(params) EVP_PKEY_free(params);
if(kctx) EVP_PKEY_CTX_free(kctx);
return key;
}
out0-corrupt.pem
Description: Binary data
out1-corrupt.pem
Description: Binary data
ec2patch.patch
Description: Binary data