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