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