Two new PKCS#12 demo programs.
Update PKCS12_parse(). Make the keyid in certificate aux info more usable.
This commit is contained in:
parent
f50c11ca40
commit
84b65340e1
10 changed files with 175 additions and 11 deletions
5
CHANGES
5
CHANGES
|
@ -4,6 +4,11 @@
|
|||
|
||||
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
|
||||
|
||||
*) Add two demo programs for PKCS12_parse() and PKCS12_create().
|
||||
Update PKCS12_parse() so it copies the friendlyName and the
|
||||
keyid to the certificates aux info.
|
||||
[Steve Henson]
|
||||
|
||||
*) Fix bug in PKCS7_verify() which caused an infinite loop
|
||||
if there was more than one signature.
|
||||
[Sven Uszpelkat <su@celocom.de>]
|
||||
|
|
12
FAQ
12
FAQ
|
@ -10,6 +10,7 @@ OpenSSL - Frequently Asked Questions
|
|||
* Why does the linker complain about undefined symbols?
|
||||
* Where can I get a compiled version of OpenSSL?
|
||||
* I've compiled a program under Windows and it crashes: why?
|
||||
* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?
|
||||
* I've called <some function> and it fails, why?
|
||||
* I just get a load of numbers for the error output, what do they mean?
|
||||
* Why do I get errors about unknown algorithms?
|
||||
|
@ -181,6 +182,17 @@ otherwise the conflict will cause a program to crash: typically on the
|
|||
first BIO related read or write operation.
|
||||
|
||||
|
||||
* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?
|
||||
|
||||
This usually happens when you try compiling something using the PKCS#12
|
||||
macros with a C++ compiler. There is hardly ever any need to use the
|
||||
PKCS#12 macros in a program, it is much easier to parse and create
|
||||
PKCS#12 files using the PKCS12_parse() and PKCS12_create() functions
|
||||
documented in doc/openssl.txt and with examples in demos/pkcs12. The
|
||||
'pkcs12' application has to use the macros because it prints out
|
||||
debugging information.
|
||||
|
||||
|
||||
* I've called <some function> and it fails, why?
|
||||
|
||||
Before submitting a report or asking in one of the mailing lists, you
|
||||
|
|
|
@ -98,5 +98,13 @@ int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
|
|||
} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
|
||||
if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
|
||||
aux->alias->data);
|
||||
if(aux->keyid) {
|
||||
BIO_printf(out, "%*sKey Id: ", indent, "");
|
||||
for(i = 0; i < aux->keyid->length; i++)
|
||||
BIO_printf(out, "%s%02X",
|
||||
i ? ":" : "",
|
||||
aux->keyid->data[i]);
|
||||
BIO_write(out,"\n",1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -153,6 +153,14 @@ int X509_alias_set1(X509 *x, unsigned char *name, int len)
|
|||
return ASN1_STRING_set(aux->alias, name, len);
|
||||
}
|
||||
|
||||
int X509_keyid_set1(X509 *x, unsigned char *id, int len)
|
||||
{
|
||||
X509_CERT_AUX *aux;
|
||||
if(!(aux = aux_get(x))) return 0;
|
||||
if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
|
||||
return ASN1_STRING_set(aux->keyid, id, len);
|
||||
}
|
||||
|
||||
unsigned char *X509_alias_get0(X509 *x, int *len)
|
||||
{
|
||||
if(!x->aux || !x->aux->alias) return NULL;
|
||||
|
|
|
@ -86,21 +86,18 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
|
|||
|
||||
/* Check for NULL PKCS12 structure */
|
||||
|
||||
if(!p12)
|
||||
{
|
||||
if(!p12) {
|
||||
PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate stack for ca certificates if needed */
|
||||
if ((ca != NULL) && (*ca == NULL))
|
||||
{
|
||||
if (!(*ca = sk_X509_new(NULL)))
|
||||
{
|
||||
if ((ca != NULL) && (*ca == NULL)) {
|
||||
if (!(*ca = sk_X509_new(NULL))) {
|
||||
PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pkey) *pkey = NULL;
|
||||
if(cert) *cert = NULL;
|
||||
|
@ -206,12 +203,17 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
|
|||
{
|
||||
PKCS8_PRIV_KEY_INFO *p8;
|
||||
X509 *x509;
|
||||
ASN1_OCTET_STRING *lkey = NULL;
|
||||
ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL;
|
||||
ASN1_TYPE *attrib;
|
||||
ASN1_BMPSTRING *fname = NULL;
|
||||
|
||||
if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
|
||||
fname = attrib->value.bmpstring;
|
||||
|
||||
if ((attrib = PKCS12_get_attr (bag, NID_localKeyID)))
|
||||
lkey = attrib->value.octet_string;
|
||||
if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) {
|
||||
lkey = attrib->value.octet_string;
|
||||
ckid = lkey;
|
||||
}
|
||||
|
||||
/* Check for any local key id matching (if needed) */
|
||||
if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) {
|
||||
|
@ -247,6 +249,18 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
|
|||
if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
|
||||
return 1;
|
||||
if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0;
|
||||
if(ckid) X509_keyid_set1(x509, ckid->data, ckid->length);
|
||||
if(fname) {
|
||||
int len;
|
||||
unsigned char *data;
|
||||
len = ASN1_STRING_to_UTF8(&data, fname);
|
||||
if(len > 0) {
|
||||
X509_alias_set1(x509, data, len);
|
||||
OPENSSL_free(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (lkey) {
|
||||
*keymatch |= MATCH_CERT;
|
||||
if (cert) *cert = x509;
|
||||
|
|
|
@ -912,6 +912,7 @@ int i2d_X509_CERT_AUX(X509_CERT_AUX *a,unsigned char **pp);
|
|||
X509_CERT_AUX * d2i_X509_CERT_AUX(X509_CERT_AUX **a,unsigned char **pp,
|
||||
long length);
|
||||
int X509_alias_set1(X509 *x, unsigned char *name, int len);
|
||||
int X509_keyid_set1(X509 *x, unsigned char *id, int len);
|
||||
unsigned char * X509_alias_get0(X509 *x, int *len);
|
||||
int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
|
||||
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
|
||||
|
|
3
demos/pkcs12/README
Normal file
3
demos/pkcs12/README
Normal file
|
@ -0,0 +1,3 @@
|
|||
PKCS#12 demo applications
|
||||
|
||||
Written by Steve Henson.
|
61
demos/pkcs12/pkread.c
Normal file
61
demos/pkcs12/pkread.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* pkread.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
|
||||
/* Simple PKCS#12 file reader */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
EVP_PKEY *pkey;
|
||||
X509 *cert;
|
||||
STACK_OF(X509) *ca = NULL;
|
||||
PKCS12 *p12;
|
||||
int i;
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "Usage: pkread p12file password opfile\n");
|
||||
exit (1);
|
||||
}
|
||||
SSLeay_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
if (!(fp = fopen(argv[1], "rb"))) {
|
||||
fprintf(stderr, "Error opening file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
p12 = d2i_PKCS12_fp(fp, NULL);
|
||||
fclose (fp);
|
||||
if (!p12) {
|
||||
fprintf(stderr, "Error reading PKCS#12 file\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit (1);
|
||||
}
|
||||
if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
|
||||
fprintf(stderr, "Error parsing PKCS#12 file\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit (1);
|
||||
}
|
||||
PKCS12_free(p12);
|
||||
if (!(fp = fopen(argv[3], "w"))) {
|
||||
fprintf(stderr, "Error opening file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if (pkey) {
|
||||
fprintf(fp, "***Private Key***\n");
|
||||
PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
|
||||
}
|
||||
if (cert) {
|
||||
fprintf(fp, "***User Certificate***\n");
|
||||
PEM_write_X509_AUX(fp, cert);
|
||||
}
|
||||
if (ca && sk_num(ca)) {
|
||||
fprintf(fp, "***Other Certificates***\n");
|
||||
for (i = 0; i < sk_X509_num(ca); i++)
|
||||
PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
46
demos/pkcs12/pkwrite.c
Normal file
46
demos/pkcs12/pkwrite.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* pkwrite.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
|
||||
/* Simple PKCS#12 file creator */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
EVP_PKEY *pkey;
|
||||
X509 *cert;
|
||||
PKCS12 *p12;
|
||||
if (argc != 5) {
|
||||
fprintf(stderr, "Usage: pkwrite infile password name p12file\n");
|
||||
exit(1);
|
||||
}
|
||||
SSLeay_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
if (!(fp = fopen(argv[1], "r"))) {
|
||||
fprintf(stderr, "Error opening file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
cert = PEM_read_X509(fp, NULL, NULL, NULL);
|
||||
rewind(fp);
|
||||
pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
|
||||
fclose(fp);
|
||||
p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0);
|
||||
if(!p12) {
|
||||
fprintf(stderr, "Error creating PKCS#12 structure\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (!(fp = fopen(argv[4], "wb"))) {
|
||||
fprintf(stderr, "Error opening file %s\n", argv[1]);
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
i2d_PKCS12_fp(fp, p12);
|
||||
PKCS12_free(p12);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
|
@ -23,6 +23,7 @@ B<openssl> B<smime>
|
|||
[B<-recip file>]
|
||||
[B<-in file>]
|
||||
[B<-inform SMIME|PEM|DER>]
|
||||
[B<-passin arg>]
|
||||
[B<-inkey file>]
|
||||
[B<-out file>]
|
||||
[B<-outform SMIME|PEM|DER>]
|
||||
|
@ -203,6 +204,11 @@ corresponding certificate. If this option is not specified then the
|
|||
private key must be included in the certificate file specified with
|
||||
the B<-recip> or B<-signer> file.
|
||||
|
||||
=item B<-passin arg>
|
||||
|
||||
the private key password source. For more information about the format of B<arg>
|
||||
see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
|
||||
|
||||
=item B<-rand file(s)>
|
||||
|
||||
a file or files containing random data used to seed the random number
|
||||
|
|
Loading…
Reference in a new issue