Re: PKCS12_parse / PKCS12_create issue

2011-02-02 Thread Muhammed Shafeek
Hi Dave,
Thank you for the detailed explanation and the suggestions. It really helped
to solve the issue.

I did use openssl tool to avoid the problem. I tried clearing the keyid and
friendly name in cert using x509__set1 fn's
before passing it to PKCS12_create and it also worked fine. I was not aware
of these api's to clear the attribute fields.
So another option i tried was by creating my own PKCS12 parse function and
removed the keyid attribute setting in cert.

Your assumption about my code snippet is right. I just provided the relevant
functions that are actually from two different functions
in my code. So fp handling is fine. Also thanks for pointing out the
discrepancy in encryption algorithm passed to PKCS12_create function.

-Shafeek

On Tue, Feb 1, 2011 at 3:01 AM, Dave Thompson dthomp...@prinpay.com wrote:

From: owner-openssl-us...@openssl.org On Behalf Of Muhammed
 Shafeek
Sent: Wednesday, 26 January, 2011 12:30

I've a program that extracts private key and cert from the input
  pfx file loaded into the system
and then create a p12 file out of this private key and cert using
  a different password to add it to a local keystore.

 You know you could use the commandline utility to do this.
 (Given it is present, or can be installed, and accessible;
 and you can write some temporary files, but if you can write
 an output file you can probably do temporaries.)

/*code to extract key*/
p12Key = d2i_PKCS12_fp(fp, NULL);
PKCS12_parse(p12Key, pass, pkey, NULL, NULL);

/*code to extract cert*/
p12Cert = d2i_PKCS12_fp(fp, NULL);
PKCS12_parse(p12Cert, pass, NULL, pCert, NULL);

 I assume you've omitted some file-management code here,
 since two d2i's from the same file open (fp) don't work.
 And you don't need them; you could call PKCS12_parse twice
 on a single (decoded) p12 object. But you shouldn't;
 one call to PKCS12_parse can get both key and cert,
 and should since they logically (must) go together.

 And you should definitely check for error(s), but I'll
 optimistically assume that was just omitted for posting.

/*creating p12 from the extracted key and cert*/
p12 = PKCS12_create(password, name, pkey, pCert, NULL,
  NID_pbe_WithSHA1And40BitRC4,NID_pbe_WithSHA1And3_Key_TripleDES_CBC,0, 0,
 0);

 It makes no security sense to encrypt the key with RC4-40,
 which nowadays is trivially brute-forced (even in the days
 of ITAR when PKCS12 was established, it was pretty easy),
 but the cert which doesn't really need privacy with TripleDES.
 The defaults, which are the other way, would be much better.

I observe the following things:
1. The attributes ptr in pkey extracted using PKCS12_parse is null.
  Note that the input pfx does have local Key ID and friendly name.
  The cert extracted using PKCS12_parse
have local Key ID attribute which is same as in input pfx file.

 Yes, p12_kiss.c returns alias=friendly and keyid for the cert
 and no attributes for the key. The man page says
  Attributes currently cannot be store in the private key
  EVP_PKEY structure.
 although that appears to be out of date.
 Perhaps it should, although friendly and keyid should be the same
 for key and cert if used at all, so getting them on the cert
 should probably usually be enough.

2. The p12 file created using PKCS12_create has a local KeyID
  attribute for private key and is different from that of cert.

 I assume you mean PKCS12_create plus i2d_PKCS12_fp or similar,
 since PKCS12_create by itself only creates a memory structure.

Can any one please explain the reason for this? Is there any issue
  in my code? or Is this an openssl issue?

 On the cert, p12_crt.c uses any friendly=alias and keyid
 in the cert object, and ADDS friendly from caller if not null
 and keyid = SHA1 of cert (if doing both keycert).
 This appears to violate PKCS9 (at least the one I have)
 which says single-valued. And isn't mentioned on the man page.
 (On the key, it just does friendly from caller and keyid = SHA1,
 but also MSCSPname and recently LocalKeySet from key.attributes!)
 Depending on the software that reads this, if it assumes
 the PKCS9 single-value rule as it apparently has a right to,
 which values get used/displayed/whatever for the cert
 may be arbitrary or even unpredictable.

 You probably should X509_alias_set1(,NULL,0) and similarly
 for keyid on your cert before giving it to PKCS12_create.

 Alternatively, but more work, build your own exactly as you want
 with the PKCS12_ PKCS7_ PKCS8_ etc. primitives.



 __
 OpenSSL Project http://www.openssl.org
 User Support Mailing Listopenssl-users@openssl.org
 Automated List Manager   majord...@openssl.org



RE: PKCS12_parse / PKCS12_create issue

2011-01-31 Thread Dave Thompson
   From: owner-openssl-us...@openssl.org On Behalf Of Muhammed Shafeek
   Sent: Wednesday, 26 January, 2011 12:30

   I've a program that extracts private key and cert from the input 
 pfx file loaded into the system
   and then create a p12 file out of this private key and cert using 
 a different password to add it to a local keystore.

You know you could use the commandline utility to do this.
(Given it is present, or can be installed, and accessible;
and you can write some temporary files, but if you can write 
an output file you can probably do temporaries.)

   /*code to extract key*/
   p12Key = d2i_PKCS12_fp(fp, NULL);
   PKCS12_parse(p12Key, pass, pkey, NULL, NULL);

   /*code to extract cert*/
   p12Cert = d2i_PKCS12_fp(fp, NULL);
   PKCS12_parse(p12Cert, pass, NULL, pCert, NULL);

I assume you've omitted some file-management code here, 
since two d2i's from the same file open (fp) don't work.
And you don't need them; you could call PKCS12_parse twice 
on a single (decoded) p12 object. But you shouldn't; 
one call to PKCS12_parse can get both key and cert, 
and should since they logically (must) go together.

And you should definitely check for error(s), but I'll 
optimistically assume that was just omitted for posting.

   /*creating p12 from the extracted key and cert*/
   p12 = PKCS12_create(password, name, pkey, pCert, NULL,
 NID_pbe_WithSHA1And40BitRC4,NID_pbe_WithSHA1And3_Key_TripleDES_CBC,0, 0,
0);

It makes no security sense to encrypt the key with RC4-40, 
which nowadays is trivially brute-forced (even in the days 
of ITAR when PKCS12 was established, it was pretty easy), 
but the cert which doesn't really need privacy with TripleDES.
The defaults, which are the other way, would be much better.

   I observe the following things:
   1. The attributes ptr in pkey extracted using PKCS12_parse is null. 
 Note that the input pfx does have local Key ID and friendly name. 
 The cert extracted using PKCS12_parse 
   have local Key ID attribute which is same as in input pfx file. 

Yes, p12_kiss.c returns alias=friendly and keyid for the cert 
and no attributes for the key. The man page says 
 Attributes currently cannot be store in the private key
 EVP_PKEY structure.
although that appears to be out of date. 
Perhaps it should, although friendly and keyid should be the same 
for key and cert if used at all, so getting them on the cert 
should probably usually be enough.

   2. The p12 file created using PKCS12_create has a local KeyID 
 attribute for private key and is different from that of cert. 

I assume you mean PKCS12_create plus i2d_PKCS12_fp or similar, 
since PKCS12_create by itself only creates a memory structure.

   Can any one please explain the reason for this? Is there any issue 
 in my code? or Is this an openssl issue? 

On the cert, p12_crt.c uses any friendly=alias and keyid 
in the cert object, and ADDS friendly from caller if not null 
and keyid = SHA1 of cert (if doing both keycert).
This appears to violate PKCS9 (at least the one I have) 
which says single-valued. And isn't mentioned on the man page.
(On the key, it just does friendly from caller and keyid = SHA1, 
but also MSCSPname and recently LocalKeySet from key.attributes!)
Depending on the software that reads this, if it assumes 
the PKCS9 single-value rule as it apparently has a right to,
which values get used/displayed/whatever for the cert 
may be arbitrary or even unpredictable.

You probably should X509_alias_set1(,NULL,0) and similarly 
for keyid on your cert before giving it to PKCS12_create. 

Alternatively, but more work, build your own exactly as you want 
with the PKCS12_ PKCS7_ PKCS8_ etc. primitives.



__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org