free NULL cleanup 7
[openssl.git] / demos / selfsign.c
1 /* NOCW */
2 /* cc -o ssdemo -I../include selfsign.c ../libcrypto.a */
3
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include <openssl/pem.h>
8 #include <openssl/conf.h>
9 #include <openssl/x509v3.h>
10
11 int mkit(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
12
13 int main()
14 {
15     BIO *bio_err;
16     X509 *x509 = NULL;
17     EVP_PKEY *pkey = NULL;
18
19     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
20
21     bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
22
23     mkit(&x509, &pkey, 512, 0, 365);
24
25     RSA_print_fp(stdout, pkey->pkey.rsa, 0);
26     X509_print_fp(stdout, x509);
27
28     PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL);
29     PEM_write_X509(stdout, x509);
30
31     X509_free(x509);
32     EVP_PKEY_free(pkey);
33
34 #ifdef CUSTOM_EXT
35     /* Only needed if we add objects or custom extensions */
36     X509V3_EXT_cleanup();
37     OBJ_cleanup();
38 #endif
39
40     CRYPTO_mem_leaks(bio_err);
41     BIO_free(bio_err);
42     return (0);
43 }
44
45 static void callback(p, n, arg)
46 int p;
47 int n;
48 void *arg;
49 {
50     char c = 'B';
51
52     if (p == 0)
53         c = '.';
54     if (p == 1)
55         c = '+';
56     if (p == 2)
57         c = '*';
58     if (p == 3)
59         c = '\n';
60     fputc(c, stderr);
61 }
62
63 int mkit(x509p, pkeyp, bits, serial, days)
64 X509 **x509p;
65 EVP_PKEY **pkeyp;
66 int bits;
67 int serial;
68 int days;
69 {
70     X509 *x;
71     EVP_PKEY *pk;
72     RSA *rsa;
73     X509_NAME *name = NULL;
74     X509_NAME_ENTRY *ne = NULL;
75     X509_EXTENSION *ex = NULL;
76
77     if ((pkeyp == NULL) || (*pkeyp == NULL)) {
78         if ((pk = EVP_PKEY_new()) == NULL) {
79             abort();
80             return (0);
81         }
82     } else
83         pk = *pkeyp;
84
85     if ((x509p == NULL) || (*x509p == NULL)) {
86         if ((x = X509_new()) == NULL)
87             goto err;
88     } else
89         x = *x509p;
90
91     rsa = RSA_generate_key(bits, RSA_F4, callback, NULL);
92     if (!EVP_PKEY_assign_RSA(pk, rsa)) {
93         abort();
94         goto err;
95     }
96     rsa = NULL;
97
98     X509_set_version(x, 3);
99     ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
100     X509_gmtime_adj(X509_get_notBefore(x), 0);
101     X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days);
102     X509_set_pubkey(x, pk);
103
104     name = X509_get_subject_name(x);
105
106     /*
107      * This function creates and adds the entry, working out the correct
108      * string type and performing checks on its length. Normally we'd check
109      * the return value for errors...
110      */
111     X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, "UK", -1, -1, 0);
112     X509_NAME_add_entry_by_txt(name, "CN",
113                                MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
114
115     X509_set_issuer_name(x, name);
116
117     /*
118      * Add extension using V3 code: we can set the config file as NULL
119      * because we wont reference any other sections. We can also set the
120      * context to NULL because none of these extensions below will need to
121      * access it.
122      */
123
124     ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_cert_type, "server");
125     X509_add_ext(x, ex, -1);
126     X509_EXTENSION_free(ex);
127
128     ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_comment,
129                              "example comment extension");
130     X509_add_ext(x, ex, -1);
131     X509_EXTENSION_free(ex);
132
133     ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_ssl_server_name,
134                              "www.openssl.org");
135
136     X509_add_ext(x, ex, -1);
137     X509_EXTENSION_free(ex);
138
139 #ifdef ADD_CA_CONSTRAINT
140     /* might want something like this too.... */
141     ex = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,
142                              "critical,CA:TRUE");
143
144     X509_add_ext(x, ex, -1);
145     X509_EXTENSION_free(ex);
146 #endif
147
148 #ifdef ADD_A_CUSTOM_EXTENSION
149     /* Maybe even add our own extension based on existing */
150     {
151         int nid;
152         nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
153         X509V3_EXT_add_alias(nid, NID_netscape_comment);
154         ex = X509V3_EXT_conf_nid(NULL, NULL, nid, "example comment alias");
155         X509_add_ext(x, ex, -1);
156         X509_EXTENSION_free(ex);
157     }
158 #endif
159
160     if (!X509_sign(x, pk, EVP_md5()))
161         goto err;
162
163     *x509p = x;
164     *pkeyp = pk;
165     return (1);
166  err:
167     return (0);
168 }