mkreq.c revision 267285
1/* Certificate request creation. Demonstrates some request related
2 * operations.
3 */
4
5#include <stdio.h>
6#include <stdlib.h>
7
8#include <openssl/pem.h>
9#include <openssl/conf.h>
10#include <openssl/x509.h>
11#include <openssl/x509v3.h>
12#ifndef OPENSSL_NO_ENGINE
13#include <openssl/engine.h>
14#endif
15
16int mkreq(X509_REQ **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
17int add_ext(STACK_OF(X509_EXTENSION) *sk, int nid, char *value);
18
19int main(int argc, char **argv)
20	{
21	BIO *bio_err;
22	X509_REQ *req=NULL;
23	EVP_PKEY *pkey=NULL;
24
25	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
26
27	bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
28
29	mkreq(&req,&pkey,512,0,365);
30
31	RSA_print_fp(stdout,pkey->pkey.rsa,0);
32	X509_REQ_print_fp(stdout,req);
33
34	PEM_write_X509_REQ(stdout,req);
35
36	X509_REQ_free(req);
37	EVP_PKEY_free(pkey);
38
39#ifndef OPENSSL_NO_ENGINE
40	ENGINE_cleanup();
41#endif
42	CRYPTO_cleanup_all_ex_data();
43
44	CRYPTO_mem_leaks(bio_err);
45	BIO_free(bio_err);
46	return(0);
47	}
48
49static void callback(int p, int n, void *arg)
50	{
51	char c='B';
52
53	if (p == 0) c='.';
54	if (p == 1) c='+';
55	if (p == 2) c='*';
56	if (p == 3) c='\n';
57	fputc(c,stderr);
58	}
59
60int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days)
61	{
62	X509_REQ *x;
63	EVP_PKEY *pk;
64	RSA *rsa;
65	X509_NAME *name=NULL;
66	STACK_OF(X509_EXTENSION) *exts = NULL;
67
68	if ((pk=EVP_PKEY_new()) == NULL)
69		goto err;
70
71	if ((x=X509_REQ_new()) == NULL)
72		goto err;
73
74	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
75	if (!EVP_PKEY_assign_RSA(pk,rsa))
76		goto err;
77
78	rsa=NULL;
79
80	X509_REQ_set_pubkey(x,pk);
81
82	name=X509_REQ_get_subject_name(x);
83
84	/* This function creates and adds the entry, working out the
85	 * correct string type and performing checks on its length.
86	 * Normally we'd check the return value for errors...
87	 */
88	X509_NAME_add_entry_by_txt(name,"C",
89				MBSTRING_ASC, "UK", -1, -1, 0);
90	X509_NAME_add_entry_by_txt(name,"CN",
91				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
92
93#ifdef REQUEST_EXTENSIONS
94	/* Certificate requests can contain extensions, which can be used
95	 * to indicate the extensions the requestor would like added to
96	 * their certificate. CAs might ignore them however or even choke
97	 * if they are present.
98	 */
99
100	/* For request extensions they are all packed in a single attribute.
101	 * We save them in a STACK and add them all at once later...
102	 */
103
104	exts = sk_X509_EXTENSION_new_null();
105	/* Standard extenions */
106
107	add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment");
108
109	/* This is a typical use for request extensions: requesting a value for
110	 * subject alternative name.
111	 */
112
113	add_ext(exts, NID_subject_alt_name, "email:steve@openssl.org");
114
115	/* Some Netscape specific extensions */
116	add_ext(exts, NID_netscape_cert_type, "client,email");
117
118
119
120#ifdef CUSTOM_EXT
121	/* Maybe even add our own extension based on existing */
122	{
123		int nid;
124		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
125		X509V3_EXT_add_alias(nid, NID_netscape_comment);
126		add_ext(x, nid, "example comment alias");
127	}
128#endif
129
130	/* Now we've created the extensions we add them to the request */
131
132	X509_REQ_add_extensions(x, exts);
133
134	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
135
136#endif
137
138	if (!X509_REQ_sign(x,pk,EVP_sha1()))
139		goto err;
140
141	*req=x;
142	*pkeyp=pk;
143	return(1);
144err:
145	return(0);
146	}
147
148/* Add extension using V3 code: we can set the config file as NULL
149 * because we wont reference any other sections.
150 */
151
152int add_ext(STACK_OF(X509_EXTENSION) *sk, int nid, char *value)
153	{
154	X509_EXTENSION *ex;
155	ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
156	if (!ex)
157		return 0;
158	sk_X509_EXTENSION_push(sk, ex);
159
160	return 1;
161	}
162
163