Commit 30b4c272 authored by Richard Levitte's avatar Richard Levitte
Browse files

Extend all the loading functions to take an engine pointer, a pass

string (some engines may have certificates protected by a PIN!) and
a description to put into error messages.

Also, have our own password callback that we can send both a password
and some prompt info to.  The default password callback in EVP assumes
that the passed parameter is a password, which isn't always the right
thing, and the ENGINE code (at least the nCipher one) makes other
assumptions...

Also, in spite of having the functions to load keys, some utilities
did the loading all by themselves...  That's changed too.
parent 2adc9293
Loading
Loading
Loading
Loading
+101 −20
Original line number Diff line number Diff line
@@ -369,6 +369,57 @@ int dump_cert_text (BIO *out, X509 *x)
        return 0;
}

int password_callback(char *buf, int bufsiz, int verify,
	PW_CB_DATA *cb_data)
	{
	int i,j;
	char prompt[80];
	const char *prompt_info = NULL;
	const char *password = NULL;

	if (cb_data)
		{
		if (cb_data->password)
			password = cb_data->password;
		if (cb_data->prompt_info)
			prompt_info = cb_data->prompt_info;
		}

	if(password) {
		i=strlen(password);
		i=(i > bufsiz)?bufsiz:i;
		memcpy(buf,password,i);
		return(i);
	}

	if (EVP_get_pw_prompt())
		BIO_snprintf(prompt, sizeof(prompt)-1, EVP_get_pw_prompt(),
			prompt_info ? prompt_info : "");
	else
		BIO_snprintf(prompt, sizeof(prompt)-1,
			"Enter pass phrase for %s:",
			prompt_info ? prompt_info : "");

	for (;;)
		{
		i=EVP_read_pw_string(buf,bufsiz,prompt,verify);
		if (i != 0)
			{
			BIO_printf(bio_err,"aborted!\n");
			memset(buf,0,(unsigned int)bufsiz);
			return(-1);
			}
		j=strlen(buf);
		if (j < PW_MIN_LENGTH)
			{
			BIO_printf(bio_err,"phrase is too short, needs to be at least %d chars\n",PW_MIN_LENGTH);
			}
		else
			break;
		}
	return(j);
	}

static char *app_get_pass(BIO *err, char *arg, int keepbio);

int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
@@ -470,7 +521,8 @@ int add_oid_section(BIO *err, LHASH *conf)
	return 1;
}

X509 *load_cert(BIO *err, char *file, int format)
X509 *load_cert(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *cert_descrip)
	{
	ASN1_HEADER *ah=NULL;
	BUF_MEM *buf=NULL;
@@ -492,7 +544,9 @@ X509 *load_cert(BIO *err, char *file, int format)
		{
		if (BIO_read_filename(cert,file) <= 0)
			{
			perror(file);
			BIO_printf(err, "Error opening %s %s\n",
				cert_descrip, file);
			ERR_print_errors(err);
			goto end;
			}
		}
@@ -543,7 +597,8 @@ X509 *load_cert(BIO *err, char *file, int format)
		ah->data=NULL;
		}
	else if (format == FORMAT_PEM)
		x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
		x=PEM_read_bio_X509_AUX(cert,NULL,
			(pem_password_cb *)password_callback, NULL);
	else if (format == FORMAT_PKCS12)
		{
		PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL);
@@ -553,7 +608,8 @@ X509 *load_cert(BIO *err, char *file, int format)
		p12 = NULL;
		}
	else	{
		BIO_printf(err,"bad input format specified for input cert\n");
		BIO_printf(err,"bad input format specified for %s\n",
			cert_descrip);
		goto end;
		}
end:
@@ -568,10 +624,15 @@ end:
	return(x);
	}

EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass, ENGINE *e)
EVP_PKEY *load_key(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *key_descrip)
	{
	BIO *key=NULL;
	EVP_PKEY *pkey=NULL;
	PW_CB_DATA cb_data;

	cb_data.password = pass;
	cb_data.prompt_info = file;

	if (file == NULL)
		{
@@ -583,7 +644,8 @@ EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass, ENGINE *e)
		if (!e)
			BIO_printf(bio_err,"no engine specified\n");
		else
			pkey = ENGINE_load_private_key(e, file, pass);
			pkey = ENGINE_load_private_key(e, file,
				(pem_password_cb *)password_callback, &cb_data);
		goto end;
		}
	key=BIO_new(BIO_s_file());
@@ -594,7 +656,8 @@ EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass, ENGINE *e)
		}
	if (BIO_read_filename(key,file) <= 0)
		{
		perror(file);
		BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
		ERR_print_errors(err);
		goto end;
		}
	if (format == FORMAT_ASN1)
@@ -603,7 +666,8 @@ EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass, ENGINE *e)
		}
	else if (format == FORMAT_PEM)
		{
		pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,pass);
		pkey=PEM_read_bio_PrivateKey(key,NULL,
			(pem_password_cb *)password_callback, &cb_data);
		}
	else if (format == FORMAT_PKCS12)
		{
@@ -615,20 +679,25 @@ EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass, ENGINE *e)
		}
	else
		{
		BIO_printf(err,"bad input format specified for key\n");
		BIO_printf(err,"bad input format specified for key file\n");
		goto end;
		}
 end:
	if (key != NULL) BIO_free(key);
	if (pkey == NULL)
		BIO_printf(err,"unable to load Private Key\n");
		BIO_printf(err,"unable to load %s\n", key_descrip);
	return(pkey);
	}

EVP_PKEY *load_pubkey(BIO *err, char *file, int format, ENGINE *e)
EVP_PKEY *load_pubkey(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *key_descrip)
	{
	BIO *key=NULL;
	EVP_PKEY *pkey=NULL;
	PW_CB_DATA cb_data;

	cb_data.password = pass;
	cb_data.prompt_info = file;

	if (file == NULL)
		{
@@ -640,7 +709,8 @@ EVP_PKEY *load_pubkey(BIO *err, char *file, int format, ENGINE *e)
		if (!e)
			BIO_printf(bio_err,"no engine specified\n");
		else
			pkey = ENGINE_load_public_key(e, file, NULL);
			pkey = ENGINE_load_public_key(e, file,
				(pem_password_cb *)password_callback, &cb_data);
		goto end;
		}
	key=BIO_new(BIO_s_file());
@@ -651,7 +721,8 @@ EVP_PKEY *load_pubkey(BIO *err, char *file, int format, ENGINE *e)
		}
	if (BIO_read_filename(key,file) <= 0)
		{
		perror(file);
		BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
		ERR_print_errors(err);
		goto end;
		}
	if (format == FORMAT_ASN1)
@@ -660,27 +731,33 @@ EVP_PKEY *load_pubkey(BIO *err, char *file, int format, ENGINE *e)
		}
	else if (format == FORMAT_PEM)
		{
		pkey=PEM_read_bio_PUBKEY(key,NULL,NULL,NULL);
		pkey=PEM_read_bio_PUBKEY(key,NULL,
			(pem_password_cb *)password_callback, &cb_data);
		}
	else
		{
		BIO_printf(err,"bad input format specified for key\n");
		BIO_printf(err,"bad input format specified for key file\n");
		goto end;
		}
 end:
	if (key != NULL) BIO_free(key);
	if (pkey == NULL)
		BIO_printf(err,"unable to load Public Key\n");
		BIO_printf(err,"unable to load %s\n", key_descrip);
	return(pkey);
	}

STACK_OF(X509) *load_certs(BIO *err, char *file, int format)
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *cert_descrip)
	{
	BIO *certs;
	int i;
	STACK_OF(X509) *othercerts = NULL;
	STACK_OF(X509_INFO) *allcerts = NULL;
	X509_INFO *xi;
	PW_CB_DATA cb_data;

	cb_data.password = pass;
	cb_data.prompt_info = file;

	if((certs = BIO_new(BIO_s_file())) == NULL)
		{
@@ -694,7 +771,9 @@ STACK_OF(X509) *load_certs(BIO *err, char *file, int format)
		{
		if (BIO_read_filename(certs,file) <= 0)
			{
			perror(file);
			BIO_printf(err, "Error opening %s %s\n",
				cert_descrip, file);
			ERR_print_errors(err);
			goto end;
			}
		}
@@ -708,7 +787,8 @@ STACK_OF(X509) *load_certs(BIO *err, char *file, int format)
			othercerts = NULL;
			goto end;
			}
		allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
		allcerts = PEM_X509_INFO_read_bio(certs, NULL,
				(pem_password_cb *)password_callback, &cb_data);
		for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
			{
			xi = sk_X509_INFO_value (allcerts, i);
@@ -721,7 +801,8 @@ STACK_OF(X509) *load_certs(BIO *err, char *file, int format)
		goto end;
		}
	else	{
		BIO_printf(err,"bad input format specified for input cert\n");
		BIO_printf(err,"bad input format specified for %s\n",
			cert_descrip);
		goto end;
		}
end:
+18 −4
Original line number Diff line number Diff line
@@ -142,6 +142,16 @@ typedef struct args_st
	int count;
	} ARGS;

#define PW_MIN_LENGTH 4
typedef struct pw_cb_data
	{
	const void *password;
	const char *prompt_info;
	} PW_CB_DATA;

int password_callback(char *buf, int bufsiz, int verify,
	PW_CB_DATA *cb_data);

int should_retry(int i);
int args_from_file(char *file, int *argc, char **argv[]);
int str2fmt(char *s);
@@ -157,10 +167,14 @@ int set_ext_copy(int *copy_type, const char *arg);
int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
int add_oid_section(BIO *err, LHASH *conf);
X509 *load_cert(BIO *err, char *file, int format);
EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass, ENGINE *e);
EVP_PKEY *load_pubkey(BIO *err, char *file, int format, ENGINE *e);
STACK_OF(X509) *load_certs(BIO *err, char *file, int format);
X509 *load_cert(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *cert_descrip);
EVP_PKEY *load_key(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *key_descrip);
EVP_PKEY *load_pubkey(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *key_descrip);
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *cert_descrip);
X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);

#define FORMAT_UNDEF    0
+3 −25
Original line number Diff line number Diff line
@@ -702,34 +702,12 @@ bad:
		BIO_printf(bio_err,"Error getting password\n");
		goto err;
		}
	if (keyform == FORMAT_ENGINE)
		{
		if (!e)
			{
			BIO_printf(bio_err,"no engine specified\n");
			goto err;
			}
		pkey = ENGINE_load_private_key(e, keyfile, key);
		}
	else if (keyform == FORMAT_PEM)
		{
		if (BIO_read_filename(in,keyfile) <= 0)
			{
			perror(keyfile);
			BIO_printf(bio_err,"trying to load CA private key\n");
			goto err;
			}
		pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
		}
	else
		{
		BIO_printf(bio_err,"bad input format specified for key file\n");
		goto err;
		}
	pkey = load_key(bio_err, keyfile, keyform, key, e, 
		"CA private key");
	if (key) memset(key,0,strlen(key));
	if (pkey == NULL)
		{
		BIO_printf(bio_err,"unable to load CA private key\n");
		/* load_key() has already printed an appropriate message */
		goto err;
		}

+8 −41
Original line number Diff line number Diff line
@@ -289,49 +289,16 @@ int MAIN(int argc, char **argv)

	if(keyfile)
		{
		if (keyform == FORMAT_PEM)
			{
			BIO *keybio;
			keybio = BIO_new_file(keyfile, "r");
			if(!keybio)
				{
				BIO_printf(bio_err,
					"Error opening key file %s\n",
					keyfile);
				ERR_print_errors(bio_err);
				goto end;
				}
			if(want_pub) 
				sigkey = PEM_read_bio_PUBKEY(keybio,
					NULL, NULL, NULL);
			else
				sigkey = PEM_read_bio_PrivateKey(keybio,
					NULL, NULL, NULL);
			BIO_free(keybio);
			}
		else if (keyform == FORMAT_ENGINE)
			{
			if (!e)
				{
				BIO_printf(bio_err,"no engine specified\n");
				goto end;
				}
		if (want_pub)
				sigkey = ENGINE_load_public_key(e, keyfile, NULL);
			else
				sigkey = ENGINE_load_private_key(e, keyfile, NULL);
			}
			sigkey = load_pubkey(bio_err, keyfile, keyform, NULL,
				e, "key file");
		else
			sigkey = load_key(bio_err, keyfile, keyform, NULL,
				e, "key file");
		if (!sigkey)
			{
			BIO_printf(bio_err,
				"bad input format specified for key file\n");
			goto end;
			}
		
		if(!sigkey) {
			BIO_printf(bio_err, "Error reading key file %s\n",
								keyfile);
			ERR_print_errors(bio_err);
			/* load_[pub]key() has already printed an appropriate
			   message */
			goto end;
			}
		}
+15 −6
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ int MAIN(int, char **);

int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	char **args;
	char *host = NULL, *port = NULL, *path = "/";
	char *reqin = NULL, *respin = NULL;
@@ -326,7 +327,8 @@ int MAIN(int argc, char **argv)
				{
				args++;
				X509_free(issuer);
				issuer = load_cert(bio_err, *args, FORMAT_PEM);
				issuer = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "issuer certificate");
				if(!issuer) goto end;
				}
			else badarg = 1;
@@ -337,7 +339,8 @@ int MAIN(int argc, char **argv)
				{
				args++;
				X509_free(cert);
				cert = load_cert(bio_err, *args, FORMAT_PEM);
				cert = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "certificate");
				if(!cert) goto end;
				if(!add_ocsp_cert(&req, cert, issuer, ids))
					goto end;
@@ -445,7 +448,8 @@ int MAIN(int argc, char **argv)
	if (signfile)
		{
		if (!keyfile) keyfile = signfile;
		signer = load_cert(bio_err, signfile, FORMAT_PEM);
		signer = load_cert(bio_err, signfile, FORMAT_PEM,
			NULL, e, "signer certificate");
		if (!signer)
			{
			BIO_printf(bio_err, "Error loading signer certificate\n");
@@ -453,13 +457,17 @@ int MAIN(int argc, char **argv)
			}
		if (sign_certfile)
			{
			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM);
			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
				NULL, e, "signer certificates");
			if (!sign_other) goto end;
			}
		key = load_key(bio_err, keyfile, FORMAT_PEM, NULL, NULL);
		key = load_key(bio_err, keyfile, FORMAT_PEM, NULL, NULL,
			"signer private key");
		if (!key)
			{
#if 0			/* An appropriate message has already been printed */
			BIO_printf(bio_err, "Error loading signer private key\n");
#endif
			goto end;
			}
		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
@@ -565,7 +573,8 @@ int MAIN(int argc, char **argv)
	if(!store) goto end;
	if (verify_certfile)
		{
		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM);
		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
			NULL, e, "validator certificate");
		if (!verify_other) goto end;
		}

Loading