mirror of
https://github.com/openssl/openssl.git
synced 2025-01-30 14:01:55 +08:00
Move the certificate and key loading functions to apps.c, so they can
be shared by several applications.
This commit is contained in:
parent
2a98f41708
commit
90ae4673a5
215
apps/apps.c
215
apps/apps.c
@ -64,6 +64,11 @@
|
||||
#define NON_MAIN
|
||||
#include "apps.h"
|
||||
#undef NON_MAIN
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/safestack.h>
|
||||
|
||||
#ifdef WINDOWS
|
||||
# include "bss_file.c"
|
||||
@ -159,6 +164,10 @@ int str2fmt(char *s)
|
||||
return(FORMAT_PEM);
|
||||
else if ((*s == 'N') || (*s == 'n'))
|
||||
return(FORMAT_NETSCAPE);
|
||||
else if ((*s == '1')
|
||||
|| (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
|
||||
|| (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
|
||||
return(FORMAT_PKCS12);
|
||||
else
|
||||
return(FORMAT_UNDEF);
|
||||
}
|
||||
@ -414,3 +423,209 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio)
|
||||
if(tmp) *tmp = 0;
|
||||
return BUF_strdup(tpass);
|
||||
}
|
||||
|
||||
X509 *load_cert(char *file, int format)
|
||||
{
|
||||
ASN1_HEADER *ah=NULL;
|
||||
BUF_MEM *buf=NULL;
|
||||
X509 *x=NULL;
|
||||
BIO *cert;
|
||||
|
||||
if ((cert=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (file == NULL)
|
||||
BIO_set_fp(cert,stdin,BIO_NOCLOSE);
|
||||
else
|
||||
{
|
||||
if (BIO_read_filename(cert,file) <= 0)
|
||||
{
|
||||
perror(file);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (format == FORMAT_ASN1)
|
||||
x=d2i_X509_bio(cert,NULL);
|
||||
else if (format == FORMAT_NETSCAPE)
|
||||
{
|
||||
unsigned char *p,*op;
|
||||
int size=0,i;
|
||||
|
||||
/* We sort of have to do it this way because it is sort of nice
|
||||
* to read the header first and check it, then
|
||||
* try to read the certificate */
|
||||
buf=BUF_MEM_new();
|
||||
for (;;)
|
||||
{
|
||||
if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
|
||||
goto end;
|
||||
i=BIO_read(cert,&(buf->data[size]),1024*10);
|
||||
size+=i;
|
||||
if (i == 0) break;
|
||||
if (i < 0)
|
||||
{
|
||||
perror("reading certificate");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
p=(unsigned char *)buf->data;
|
||||
op=p;
|
||||
|
||||
/* First load the header */
|
||||
if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
|
||||
goto end;
|
||||
if ((ah->header == NULL) || (ah->header->data == NULL) ||
|
||||
(strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data,
|
||||
ah->header->length) != 0))
|
||||
{
|
||||
BIO_printf(bio_err,"Error reading header on certificate\n");
|
||||
goto end;
|
||||
}
|
||||
/* header is ok, so now read the object */
|
||||
p=op;
|
||||
ah->meth=X509_asn1_meth();
|
||||
if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
|
||||
goto end;
|
||||
x=(X509 *)ah->data;
|
||||
ah->data=NULL;
|
||||
}
|
||||
else if (format == FORMAT_PEM)
|
||||
x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
|
||||
else if (format == FORMAT_PKCS12)
|
||||
{
|
||||
PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL);
|
||||
|
||||
PKCS12_parse(p12, NULL, NULL, &x, NULL);
|
||||
PKCS12_free(p12);
|
||||
p12 = NULL;
|
||||
}
|
||||
else {
|
||||
BIO_printf(bio_err,"bad input format specified for input cert\n");
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
if (x == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"unable to load certificate\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
if (ah != NULL) ASN1_HEADER_free(ah);
|
||||
if (cert != NULL) BIO_free(cert);
|
||||
if (buf != NULL) BUF_MEM_free(buf);
|
||||
return(x);
|
||||
}
|
||||
|
||||
EVP_PKEY *load_key(char *file, int format, char *pass)
|
||||
{
|
||||
BIO *key=NULL;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"no keyfile specified\n");
|
||||
goto end;
|
||||
}
|
||||
key=BIO_new(BIO_s_file());
|
||||
if (key == NULL)
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (BIO_read_filename(key,file) <= 0)
|
||||
{
|
||||
perror(file);
|
||||
goto end;
|
||||
}
|
||||
if (format == FORMAT_ASN1)
|
||||
{
|
||||
pkey=d2i_PrivateKey_bio(key, NULL);
|
||||
}
|
||||
else if (format == FORMAT_PEM)
|
||||
{
|
||||
pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,pass);
|
||||
}
|
||||
else if (format == FORMAT_PKCS12)
|
||||
{
|
||||
PKCS12 *p12 = d2i_PKCS12_bio(key, NULL);
|
||||
|
||||
PKCS12_parse(p12, pass, &pkey, NULL, NULL);
|
||||
PKCS12_free(p12);
|
||||
p12 = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err,"bad input format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
if (key != NULL) BIO_free(key);
|
||||
if (pkey == NULL)
|
||||
BIO_printf(bio_err,"unable to load Private Key\n");
|
||||
return(pkey);
|
||||
}
|
||||
|
||||
STACK_OF(X509) *load_certs(char *file, int format)
|
||||
{
|
||||
BIO *certs;
|
||||
int i;
|
||||
STACK_OF(X509) *othercerts = NULL;
|
||||
STACK_OF(X509_INFO) *allcerts = NULL;
|
||||
X509_INFO *xi;
|
||||
|
||||
if((certs = BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (file == NULL)
|
||||
BIO_set_fp(certs,stdin,BIO_NOCLOSE);
|
||||
else
|
||||
{
|
||||
if (BIO_read_filename(certs,file) <= 0)
|
||||
{
|
||||
perror(file);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (format == FORMAT_PEM)
|
||||
{
|
||||
othercerts = sk_X509_new(NULL);
|
||||
if(!othercerts)
|
||||
{
|
||||
sk_X509_free(othercerts);
|
||||
othercerts = NULL;
|
||||
goto end;
|
||||
}
|
||||
allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
|
||||
for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
|
||||
{
|
||||
xi = sk_X509_INFO_value (allcerts, i);
|
||||
if (xi->x509)
|
||||
{
|
||||
sk_X509_push(othercerts, xi->x509);
|
||||
xi->x509 = NULL;
|
||||
}
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
else {
|
||||
BIO_printf(bio_err,"bad input format specified for input cert\n");
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
if (othercerts == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"unable to load certificates\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
|
||||
if (certs != NULL) BIO_free(certs);
|
||||
return(othercerts);
|
||||
}
|
||||
|
||||
|
@ -146,11 +146,18 @@ int chopup_args(ARGS *arg,char *buf, int *argc, char **argv[]);
|
||||
int dump_cert_text(BIO *out, X509 *x);
|
||||
#endif
|
||||
int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
|
||||
X509 *load_cert(char *file, int format);
|
||||
EVP_PKEY *load_key(char *file, int format, char *pass);
|
||||
STACK_OF(X509) *load_certs(char *file, int format);
|
||||
|
||||
#define FORMAT_UNDEF 0
|
||||
#define FORMAT_ASN1 1
|
||||
#define FORMAT_TEXT 2
|
||||
#define FORMAT_PEM 3
|
||||
#define FORMAT_NETSCAPE 4
|
||||
#define FORMAT_PKCS12 5
|
||||
|
||||
#define NETSCAPE_CERT_HDR "certificate"
|
||||
|
||||
#define APP_PASS_LEN 1024
|
||||
|
||||
|
56
apps/smime.c
56
apps/smime.c
@ -67,9 +67,6 @@
|
||||
|
||||
#undef PROG
|
||||
#define PROG smime_main
|
||||
static X509 *load_cert(char *file);
|
||||
static EVP_PKEY *load_key(char *file, char *pass);
|
||||
static STACK_OF(X509) *load_certs(char *file);
|
||||
static X509_STORE *setup_verify(char *CAfile, char *CApath);
|
||||
static int save_certs(char *signerfile, STACK_OF(X509) *signers);
|
||||
|
||||
@ -311,7 +308,7 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
encerts = sk_X509_new_null();
|
||||
while (*args) {
|
||||
if(!(cert = load_cert(*args))) {
|
||||
if(!(cert = load_cert(*args,FORMAT_PEM))) {
|
||||
BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args);
|
||||
goto end;
|
||||
}
|
||||
@ -322,14 +319,14 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
|
||||
if(signerfile && (operation == SMIME_SIGN)) {
|
||||
if(!(signer = load_cert(signerfile))) {
|
||||
if(!(signer = load_cert(signerfile,FORMAT_PEM))) {
|
||||
BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if(certfile) {
|
||||
if(!(other = load_certs(certfile))) {
|
||||
if(!(other = load_certs(certfile,FORMAT_PEM))) {
|
||||
BIO_printf(bio_err, "Can't read certificate file %s\n", certfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
@ -337,7 +334,7 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
|
||||
if(recipfile && (operation == SMIME_DECRYPT)) {
|
||||
if(!(recip = load_cert(recipfile))) {
|
||||
if(!(recip = load_cert(recipfile,FORMAT_PEM))) {
|
||||
BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
@ -351,7 +348,7 @@ int MAIN(int argc, char **argv)
|
||||
} else keyfile = NULL;
|
||||
|
||||
if(keyfile) {
|
||||
if(!(key = load_key(keyfile, passin))) {
|
||||
if(!(key = load_key(keyfile, FORMAT_PEM, passin))) {
|
||||
BIO_printf(bio_err, "Can't read recipient certificate file %s\n", keyfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
@ -447,49 +444,6 @@ end:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static X509 *load_cert(char *file)
|
||||
{
|
||||
BIO *in;
|
||||
X509 *cert;
|
||||
if(!(in = BIO_new_file(file, "r"))) return NULL;
|
||||
cert = PEM_read_bio_X509(in, NULL, NULL,NULL);
|
||||
BIO_free(in);
|
||||
return cert;
|
||||
}
|
||||
|
||||
static EVP_PKEY *load_key(char *file, char *pass)
|
||||
{
|
||||
BIO *in;
|
||||
EVP_PKEY *key;
|
||||
if(!(in = BIO_new_file(file, "r"))) return NULL;
|
||||
key = PEM_read_bio_PrivateKey(in, NULL,NULL,pass);
|
||||
BIO_free(in);
|
||||
return key;
|
||||
}
|
||||
|
||||
static STACK_OF(X509) *load_certs(char *file)
|
||||
{
|
||||
BIO *in;
|
||||
int i;
|
||||
STACK_OF(X509) *othercerts;
|
||||
STACK_OF(X509_INFO) *allcerts;
|
||||
X509_INFO *xi;
|
||||
if(!(in = BIO_new_file(file, "r"))) return NULL;
|
||||
othercerts = sk_X509_new(NULL);
|
||||
if(!othercerts) return NULL;
|
||||
allcerts = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
|
||||
for(i = 0; i < sk_X509_INFO_num(allcerts); i++) {
|
||||
xi = sk_X509_INFO_value (allcerts, i);
|
||||
if (xi->x509) {
|
||||
sk_X509_push(othercerts, xi->x509);
|
||||
xi->x509 = NULL;
|
||||
}
|
||||
}
|
||||
sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
|
||||
BIO_free(in);
|
||||
return othercerts;
|
||||
}
|
||||
|
||||
static X509_STORE *setup_verify(char *CAfile, char *CApath)
|
||||
{
|
||||
X509_STORE *store;
|
||||
|
135
apps/x509.c
135
apps/x509.c
@ -81,8 +81,6 @@
|
||||
#define POSTFIX ".srl"
|
||||
#define DEF_DAYS 30
|
||||
|
||||
#define CERT_HDR "certificate"
|
||||
|
||||
static char *x509_usage[]={
|
||||
"usage: x509 args\n",
|
||||
" -inform arg - input format - default PEM (one of DER, NET or PEM)\n",
|
||||
@ -134,8 +132,6 @@ NULL
|
||||
};
|
||||
|
||||
static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
|
||||
static EVP_PKEY *load_key(char *file, int format, char *passin);
|
||||
static X509 *load_cert(char *file, int format);
|
||||
static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
|
||||
LHASH *conf, char *section);
|
||||
static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
|
||||
@ -894,8 +890,8 @@ bad:
|
||||
ASN1_HEADER ah;
|
||||
ASN1_OCTET_STRING os;
|
||||
|
||||
os.data=(unsigned char *)CERT_HDR;
|
||||
os.length=strlen(CERT_HDR);
|
||||
os.data=(unsigned char *)NETSCAPE_CERT_HDR;
|
||||
os.length=strlen(NETSCAPE_CERT_HDR);
|
||||
ah.header= &os;
|
||||
ah.data=(char *)x;
|
||||
ah.meth=X509_asn1_meth();
|
||||
@ -1114,133 +1110,6 @@ static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static EVP_PKEY *load_key(char *file, int format, char *passin)
|
||||
{
|
||||
BIO *key=NULL;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"no keyfile specified\n");
|
||||
goto end;
|
||||
}
|
||||
key=BIO_new(BIO_s_file());
|
||||
if (key == NULL)
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (BIO_read_filename(key,file) <= 0)
|
||||
{
|
||||
perror(file);
|
||||
goto end;
|
||||
}
|
||||
if (format == FORMAT_ASN1)
|
||||
{
|
||||
pkey=d2i_PrivateKey_bio(key, NULL);
|
||||
}
|
||||
else if (format == FORMAT_PEM)
|
||||
{
|
||||
pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,passin);
|
||||
}
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err,"bad input format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
if (key != NULL) BIO_free(key);
|
||||
if (pkey == NULL)
|
||||
BIO_printf(bio_err,"unable to load Private Key\n");
|
||||
return(pkey);
|
||||
}
|
||||
|
||||
static X509 *load_cert(char *file, int format)
|
||||
{
|
||||
ASN1_HEADER *ah=NULL;
|
||||
BUF_MEM *buf=NULL;
|
||||
X509 *x=NULL;
|
||||
BIO *cert;
|
||||
|
||||
if ((cert=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (file == NULL)
|
||||
BIO_set_fp(cert,stdin,BIO_NOCLOSE);
|
||||
else
|
||||
{
|
||||
if (BIO_read_filename(cert,file) <= 0)
|
||||
{
|
||||
perror(file);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (format == FORMAT_ASN1)
|
||||
x=d2i_X509_bio(cert,NULL);
|
||||
else if (format == FORMAT_NETSCAPE)
|
||||
{
|
||||
unsigned char *p,*op;
|
||||
int size=0,i;
|
||||
|
||||
/* We sort of have to do it this way because it is sort of nice
|
||||
* to read the header first and check it, then
|
||||
* try to read the certificate */
|
||||
buf=BUF_MEM_new();
|
||||
for (;;)
|
||||
{
|
||||
if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
|
||||
goto end;
|
||||
i=BIO_read(cert,&(buf->data[size]),1024*10);
|
||||
size+=i;
|
||||
if (i == 0) break;
|
||||
if (i < 0)
|
||||
{
|
||||
perror("reading certificate");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
p=(unsigned char *)buf->data;
|
||||
op=p;
|
||||
|
||||
/* First load the header */
|
||||
if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
|
||||
goto end;
|
||||
if ((ah->header == NULL) || (ah->header->data == NULL) ||
|
||||
(strncmp(CERT_HDR,(char *)ah->header->data,
|
||||
ah->header->length) != 0))
|
||||
{
|
||||
BIO_printf(bio_err,"Error reading header on certificate\n");
|
||||
goto end;
|
||||
}
|
||||
/* header is ok, so now read the object */
|
||||
p=op;
|
||||
ah->meth=X509_asn1_meth();
|
||||
if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
|
||||
goto end;
|
||||
x=(X509 *)ah->data;
|
||||
ah->data=NULL;
|
||||
}
|
||||
else if (format == FORMAT_PEM)
|
||||
x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
|
||||
else {
|
||||
BIO_printf(bio_err,"bad input format specified for input cert\n");
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
if (x == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"unable to load certificate\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
if (ah != NULL) ASN1_HEADER_free(ah);
|
||||
if (cert != NULL) BIO_free(cert);
|
||||
if (buf != NULL) BUF_MEM_free(buf);
|
||||
return(x);
|
||||
}
|
||||
|
||||
/* self sign */
|
||||
static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
|
||||
LHASH *conf, char *section)
|
||||
|
Loading…
Reference in New Issue
Block a user