OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
mkreq.c
Go to the documentation of this file.
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 
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
40 #endif
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 
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  */
88  MBSTRING_ASC, "UK", -1, -1, 0);
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 
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 
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");
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  {
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