xref: /minix3/crypto/external/bsd/openssl/dist/demos/x509/mkcert.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*
2*0a6a1f1dSLionel Sambuc  * Certificate creation. Demonstrates some certificate related operations.
3ebfedea0SLionel Sambuc  */
4ebfedea0SLionel Sambuc 
5ebfedea0SLionel Sambuc #include <stdio.h>
6ebfedea0SLionel Sambuc #include <stdlib.h>
7ebfedea0SLionel Sambuc 
8ebfedea0SLionel Sambuc #include <openssl/pem.h>
9ebfedea0SLionel Sambuc #include <openssl/conf.h>
10ebfedea0SLionel Sambuc #include <openssl/x509v3.h>
11ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_ENGINE
12ebfedea0SLionel Sambuc # include <openssl/engine.h>
13ebfedea0SLionel Sambuc #endif
14ebfedea0SLionel Sambuc 
15ebfedea0SLionel Sambuc int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
16ebfedea0SLionel Sambuc int add_ext(X509 *cert, int nid, char *value);
17ebfedea0SLionel Sambuc 
main(int argc,char ** argv)18ebfedea0SLionel Sambuc int main(int argc, char **argv)
19ebfedea0SLionel Sambuc {
20ebfedea0SLionel Sambuc     BIO *bio_err;
21ebfedea0SLionel Sambuc     X509 *x509 = NULL;
22ebfedea0SLionel Sambuc     EVP_PKEY *pkey = NULL;
23ebfedea0SLionel Sambuc 
24ebfedea0SLionel Sambuc     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
25ebfedea0SLionel Sambuc 
26ebfedea0SLionel Sambuc     bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
27ebfedea0SLionel Sambuc 
28ebfedea0SLionel Sambuc     mkcert(&x509, &pkey, 512, 0, 365);
29ebfedea0SLionel Sambuc 
30ebfedea0SLionel Sambuc     RSA_print_fp(stdout, pkey->pkey.rsa, 0);
31ebfedea0SLionel Sambuc     X509_print_fp(stdout, x509);
32ebfedea0SLionel Sambuc 
33ebfedea0SLionel Sambuc     PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL);
34ebfedea0SLionel Sambuc     PEM_write_X509(stdout, x509);
35ebfedea0SLionel Sambuc 
36ebfedea0SLionel Sambuc     X509_free(x509);
37ebfedea0SLionel Sambuc     EVP_PKEY_free(pkey);
38ebfedea0SLionel Sambuc 
39ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_ENGINE
40ebfedea0SLionel Sambuc     ENGINE_cleanup();
41ebfedea0SLionel Sambuc #endif
42ebfedea0SLionel Sambuc     CRYPTO_cleanup_all_ex_data();
43ebfedea0SLionel Sambuc 
44ebfedea0SLionel Sambuc     CRYPTO_mem_leaks(bio_err);
45ebfedea0SLionel Sambuc     BIO_free(bio_err);
46ebfedea0SLionel Sambuc     return (0);
47ebfedea0SLionel Sambuc }
48ebfedea0SLionel Sambuc 
callback(int p,int n,void * arg)49ebfedea0SLionel Sambuc static void callback(int p, int n, void *arg)
50ebfedea0SLionel Sambuc {
51ebfedea0SLionel Sambuc     char c = 'B';
52ebfedea0SLionel Sambuc 
53*0a6a1f1dSLionel Sambuc     if (p == 0)
54*0a6a1f1dSLionel Sambuc         c = '.';
55*0a6a1f1dSLionel Sambuc     if (p == 1)
56*0a6a1f1dSLionel Sambuc         c = '+';
57*0a6a1f1dSLionel Sambuc     if (p == 2)
58*0a6a1f1dSLionel Sambuc         c = '*';
59*0a6a1f1dSLionel Sambuc     if (p == 3)
60*0a6a1f1dSLionel Sambuc         c = '\n';
61ebfedea0SLionel Sambuc     fputc(c, stderr);
62ebfedea0SLionel Sambuc }
63ebfedea0SLionel Sambuc 
mkcert(X509 ** x509p,EVP_PKEY ** pkeyp,int bits,int serial,int days)64ebfedea0SLionel Sambuc int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
65ebfedea0SLionel Sambuc {
66ebfedea0SLionel Sambuc     X509 *x;
67ebfedea0SLionel Sambuc     EVP_PKEY *pk;
68ebfedea0SLionel Sambuc     RSA *rsa;
69ebfedea0SLionel Sambuc     X509_NAME *name = NULL;
70ebfedea0SLionel Sambuc 
71*0a6a1f1dSLionel Sambuc     if ((pkeyp == NULL) || (*pkeyp == NULL)) {
72*0a6a1f1dSLionel Sambuc         if ((pk = EVP_PKEY_new()) == NULL) {
73ebfedea0SLionel Sambuc             abort();
74ebfedea0SLionel Sambuc             return (0);
75ebfedea0SLionel Sambuc         }
76*0a6a1f1dSLionel Sambuc     } else
77ebfedea0SLionel Sambuc         pk = *pkeyp;
78ebfedea0SLionel Sambuc 
79*0a6a1f1dSLionel Sambuc     if ((x509p == NULL) || (*x509p == NULL)) {
80ebfedea0SLionel Sambuc         if ((x = X509_new()) == NULL)
81ebfedea0SLionel Sambuc             goto err;
82*0a6a1f1dSLionel Sambuc     } else
83ebfedea0SLionel Sambuc         x = *x509p;
84ebfedea0SLionel Sambuc 
85ebfedea0SLionel Sambuc     rsa = RSA_generate_key(bits, RSA_F4, callback, NULL);
86*0a6a1f1dSLionel Sambuc     if (!EVP_PKEY_assign_RSA(pk, rsa)) {
87ebfedea0SLionel Sambuc         abort();
88ebfedea0SLionel Sambuc         goto err;
89ebfedea0SLionel Sambuc     }
90ebfedea0SLionel Sambuc     rsa = NULL;
91ebfedea0SLionel Sambuc 
92ebfedea0SLionel Sambuc     X509_set_version(x, 2);
93ebfedea0SLionel Sambuc     ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
94ebfedea0SLionel Sambuc     X509_gmtime_adj(X509_get_notBefore(x), 0);
95ebfedea0SLionel Sambuc     X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days);
96ebfedea0SLionel Sambuc     X509_set_pubkey(x, pk);
97ebfedea0SLionel Sambuc 
98ebfedea0SLionel Sambuc     name = X509_get_subject_name(x);
99ebfedea0SLionel Sambuc 
100*0a6a1f1dSLionel Sambuc     /*
101*0a6a1f1dSLionel Sambuc      * This function creates and adds the entry, working out the correct
102*0a6a1f1dSLionel Sambuc      * string type and performing checks on its length. Normally we'd check
103*0a6a1f1dSLionel Sambuc      * the return value for errors...
104ebfedea0SLionel Sambuc      */
105*0a6a1f1dSLionel Sambuc     X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, "UK", -1, -1, 0);
106ebfedea0SLionel Sambuc     X509_NAME_add_entry_by_txt(name, "CN",
107ebfedea0SLionel Sambuc                                MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
108ebfedea0SLionel Sambuc 
109*0a6a1f1dSLionel Sambuc     /*
110*0a6a1f1dSLionel Sambuc      * Its self signed so set the issuer name to be the same as the subject.
111ebfedea0SLionel Sambuc      */
112ebfedea0SLionel Sambuc     X509_set_issuer_name(x, name);
113ebfedea0SLionel Sambuc 
114ebfedea0SLionel Sambuc     /* Add various extensions: standard extensions */
115ebfedea0SLionel Sambuc     add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
116ebfedea0SLionel Sambuc     add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");
117ebfedea0SLionel Sambuc 
118ebfedea0SLionel Sambuc     add_ext(x, NID_subject_key_identifier, "hash");
119ebfedea0SLionel Sambuc 
120ebfedea0SLionel Sambuc     /* Some Netscape specific extensions */
121ebfedea0SLionel Sambuc     add_ext(x, NID_netscape_cert_type, "sslCA");
122ebfedea0SLionel Sambuc 
123ebfedea0SLionel Sambuc     add_ext(x, NID_netscape_comment, "example comment extension");
124ebfedea0SLionel Sambuc 
125ebfedea0SLionel Sambuc #ifdef CUSTOM_EXT
126ebfedea0SLionel Sambuc     /* Maybe even add our own extension based on existing */
127ebfedea0SLionel Sambuc     {
128ebfedea0SLionel Sambuc         int nid;
129ebfedea0SLionel Sambuc         nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
130ebfedea0SLionel Sambuc         X509V3_EXT_add_alias(nid, NID_netscape_comment);
131ebfedea0SLionel Sambuc         add_ext(x, nid, "example comment alias");
132ebfedea0SLionel Sambuc     }
133ebfedea0SLionel Sambuc #endif
134ebfedea0SLionel Sambuc 
135ebfedea0SLionel Sambuc     if (!X509_sign(x, pk, EVP_sha1()))
136ebfedea0SLionel Sambuc         goto err;
137ebfedea0SLionel Sambuc 
138ebfedea0SLionel Sambuc     *x509p = x;
139ebfedea0SLionel Sambuc     *pkeyp = pk;
140ebfedea0SLionel Sambuc     return (1);
141ebfedea0SLionel Sambuc  err:
142ebfedea0SLionel Sambuc     return (0);
143ebfedea0SLionel Sambuc }
144ebfedea0SLionel Sambuc 
145*0a6a1f1dSLionel Sambuc /*
146*0a6a1f1dSLionel Sambuc  * Add extension using V3 code: we can set the config file as NULL because we
147*0a6a1f1dSLionel Sambuc  * wont reference any other sections.
148ebfedea0SLionel Sambuc  */
149ebfedea0SLionel Sambuc 
add_ext(X509 * cert,int nid,char * value)150ebfedea0SLionel Sambuc int add_ext(X509 *cert, int nid, char *value)
151ebfedea0SLionel Sambuc {
152ebfedea0SLionel Sambuc     X509_EXTENSION *ex;
153ebfedea0SLionel Sambuc     X509V3_CTX ctx;
154ebfedea0SLionel Sambuc     /* This sets the 'context' of the extensions. */
155ebfedea0SLionel Sambuc     /* No configuration database */
156ebfedea0SLionel Sambuc     X509V3_set_ctx_nodb(&ctx);
157*0a6a1f1dSLionel Sambuc     /*
158*0a6a1f1dSLionel Sambuc      * Issuer and subject certs: both the target since it is self signed, no
159*0a6a1f1dSLionel Sambuc      * request and no CRL
160ebfedea0SLionel Sambuc      */
161ebfedea0SLionel Sambuc     X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
162ebfedea0SLionel Sambuc     ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
163ebfedea0SLionel Sambuc     if (!ex)
164ebfedea0SLionel Sambuc         return 0;
165ebfedea0SLionel Sambuc 
166ebfedea0SLionel Sambuc     X509_add_ext(cert, ex, -1);
167ebfedea0SLionel Sambuc     X509_EXTENSION_free(ex);
168ebfedea0SLionel Sambuc     return 1;
169ebfedea0SLionel Sambuc }
170