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