Blame
Date:
Tue Apr 12 17:40:58 2022 UTC
Message:
log when the certificate was successfully generated
001
2021-01-27
op
/*
002
2021-01-28
op
* Copyright (c) 2021 Omar Polo <op@omarpolo.com>
003
2021-01-27
op
*
004
2021-01-27
op
* Permission to use, copy, modify, and distribute this software for any
005
2021-01-27
op
* purpose with or without fee is hereby granted, provided that the above
006
2021-01-27
op
* copyright notice and this permission notice appear in all copies.
007
2021-01-27
op
*
008
2021-01-27
op
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
009
2021-01-27
op
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
010
2021-01-27
op
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
011
2021-01-27
op
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
012
2021-01-27
op
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
013
2021-01-27
op
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
014
2021-01-27
op
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
015
2021-01-27
op
*/
016
2021-01-27
op
017
2021-02-12
op
#include "gmid.h"
018
2021-02-12
op
019
2021-01-27
op
#include <errno.h>
020
2021-01-27
op
#include <string.h>
021
2021-01-27
op
022
2021-02-10
op
#include <openssl/bn.h>
023
2021-02-07
op
#include <openssl/pem.h>
024
2021-02-09
op
#include <openssl/x509_vfy.h>
025
2021-02-09
op
#include <openssl/x509v3.h>
026
2021-02-07
op
027
2021-01-27
op
int
028
2021-01-27
op
starts_with(const char *str, const char *prefix)
029
2021-01-27
op
{
030
2021-01-27
op
size_t i;
031
2021-01-27
op
032
2021-01-27
op
if (prefix == NULL)
033
2021-01-27
op
return 0;
034
2021-01-27
op
035
2021-01-27
op
for (i = 0; prefix[i] != '\0'; ++i)
036
2021-01-27
op
if (str[i] != prefix[i])
037
2021-01-27
op
return 0;
038
2021-01-27
op
return 1;
039
2021-01-27
op
}
040
2021-01-27
op
041
2021-01-27
op
int
042
2021-01-27
op
ends_with(const char *str, const char *sufx)
043
2021-01-27
op
{
044
2021-01-27
op
size_t i, j;
045
2021-01-27
op
046
2021-01-27
op
i = strlen(str);
047
2021-01-27
op
j = strlen(sufx);
048
2021-01-27
op
049
2021-01-27
op
if (j > i)
050
2021-01-27
op
return 0;
051
2021-01-27
op
052
2021-01-27
op
i -= j;
053
2021-01-27
op
for (j = 0; str[i] != '\0'; i++, j++)
054
2021-01-27
op
if (str[i] != sufx[j])
055
2021-01-27
op
return 0;
056
2021-01-27
op
return 1;
057
2021-01-27
op
}
058
2021-01-27
op
059
2021-01-27
op
ssize_t
060
2021-01-27
op
filesize(int fd)
061
2021-01-27
op
{
062
2021-01-27
op
ssize_t len;
063
2021-01-27
op
064
2021-01-27
op
if ((len = lseek(fd, 0, SEEK_END)) == -1)
065
2021-01-27
op
return -1;
066
2021-01-27
op
if (lseek(fd, 0, SEEK_SET) == -1)
067
2021-01-27
op
return -1;
068
2021-01-27
op
return len;
069
2021-01-27
op
}
070
2021-02-01
op
071
2021-02-01
op
char *
072
2021-02-01
op
absolutify_path(const char *path)
073
2021-02-01
op
{
074
2021-02-01
op
char *wd, *r;
075
2021-02-01
op
076
2021-02-01
op
if (*path == '/') {
077
2021-02-01
op
if ((r = strdup(path)) == NULL)
078
2021-02-01
op
err(1, "strdup");
079
2021-02-01
op
return r;
080
2021-02-01
op
}
081
2021-02-01
op
082
2021-02-01
op
wd = getcwd(NULL, 0);
083
2021-02-01
op
if (asprintf(&r, "%s/%s", wd, path) == -1)
084
2021-02-01
op
err(1, "asprintf");
085
2021-02-01
op
free(wd);
086
2021-02-01
op
return r;
087
2021-02-01
op
}
088
2021-02-04
op
089
2021-02-04
op
char *
090
2021-02-04
op
xstrdup(const char *s)
091
2021-02-04
op
{
092
2021-02-04
op
char *d;
093
2021-02-04
op
094
2021-02-04
op
if ((d = strdup(s)) == NULL)
095
2021-02-04
op
err(1, "strdup");
096
2021-03-31
op
return d;
097
2021-03-31
op
}
098
2021-03-31
op
099
2021-03-31
op
void *
100
2021-03-31
op
xcalloc(size_t nmemb, size_t size)
101
2021-03-31
op
{
102
2021-03-31
op
void *d;
103
2021-03-31
op
104
2021-03-31
op
if ((d = calloc(nmemb, size)) == NULL)
105
2021-03-31
op
err(1, "calloc");
106
2021-02-04
op
return d;
107
2021-02-04
op
}
108
2021-02-07
op
109
2021-02-07
op
void
110
2021-02-12
op
gen_certificate(const char *hostname, const char *certpath, const char *keypath)
111
2021-02-07
op
{
112
2021-02-10
op
BIGNUM *e;
113
2021-02-07
op
EVP_PKEY *pkey;
114
2021-02-07
op
RSA *rsa;
115
2021-02-07
op
X509 *x509;
116
2021-02-07
op
X509_NAME *name;
117
2021-02-07
op
FILE *f;
118
2021-02-12
op
const unsigned char *host = (const unsigned char*)hostname;
119
2021-02-07
op
120
2021-02-07
op
log_notice(NULL,
121
2021-02-07
op
"generating new certificate for %s (it could take a while)",
122
2021-02-07
op
host);
123
2021-02-07
op
124
2021-02-07
op
if ((pkey = EVP_PKEY_new()) == NULL)
125
2021-10-18
op
fatal("couldn't create a new private key");
126
2021-02-07
op
127
2021-02-07
op
if ((rsa = RSA_new()) == NULL)
128
2021-02-10
op
fatal("couldn't generate rsa");
129
2021-02-07
op
130
2021-02-10
op
if ((e = BN_new()) == NULL)
131
2021-02-10
op
fatal("couldn't allocate a bignum");
132
2021-02-10
op
133
2021-05-12
op
BN_set_word(e, RSA_F4);
134
2021-02-10
op
if (!RSA_generate_key_ex(rsa, 4096, e, NULL))
135
2021-02-07
op
fatal("couldn't generate a rsa key");
136
2021-02-07
op
137
2021-02-07
op
if (!EVP_PKEY_assign_RSA(pkey, rsa))
138
2021-02-07
op
fatal("couldn't assign the key");
139
2021-02-07
op
140
2021-02-07
op
if ((x509 = X509_new()) == NULL)
141
2021-02-07
op
fatal("couldn't generate the X509 certificate");
142
2021-02-07
op
143
2021-05-12
op
ASN1_INTEGER_set(X509_get_serialNumber(x509), 0);
144
2021-02-07
op
X509_gmtime_adj(X509_get_notBefore(x509), 0);
145
2021-02-07
op
X509_gmtime_adj(X509_get_notAfter(x509), 315360000L); /* 10 years */
146
2021-05-12
op
X509_set_version(x509, 3);
147
2021-02-07
op
148
2021-02-07
op
if (!X509_set_pubkey(x509, pkey))
149
2021-02-07
op
fatal("couldn't set the public key");
150
2021-02-07
op
151
2021-02-07
op
name = X509_get_subject_name(x509);
152
2021-02-07
op
if (!X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, host, -1, -1, 0))
153
2021-02-07
op
fatal("couldn't add CN to cert");
154
2021-02-07
op
X509_set_issuer_name(x509, name);
155
2021-02-07
op
156
2021-02-07
op
if (!X509_sign(x509, pkey, EVP_sha256()))
157
2021-10-18
op
fatal("couldn't sign the certificate");
158
2021-02-07
op
159
2021-02-07
op
if ((f = fopen(keypath, "w")) == NULL)
160
2021-02-07
op
fatal("fopen(%s): %s", keypath, strerror(errno));
161
2021-02-07
op
if (!PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL))
162
2021-02-07
op
fatal("couldn't write private key");
163
2021-02-07
op
fclose(f);
164
2021-02-07
op
165
2021-02-07
op
if ((f = fopen(certpath, "w")) == NULL)
166
2021-02-07
op
fatal("fopen(%s): %s", certpath, strerror(errno));
167
2021-02-07
op
if (!PEM_write_X509(f, x509))
168
2021-02-07
op
fatal("couldn't write cert");
169
2021-02-07
op
fclose(f);
170
2021-02-07
op
171
2021-02-10
op
BN_free(e);
172
2021-02-07
op
X509_free(x509);
173
2021-02-07
op
RSA_free(rsa);
174
2022-04-12
op
175
2022-04-12
op
log_notice(NULL, "certificate successfully generated");
176
2021-02-07
op
}
177
2021-02-09
op
178
2021-02-09
op
X509_STORE *
179
2021-02-09
op
load_ca(const char *path)
180
2021-02-09
op
{
181
2021-02-09
op
FILE *f = NULL;
182
2021-02-09
op
X509 *x = NULL;
183
2021-02-09
op
X509_STORE *store;
184
2021-02-09
op
185
2021-02-09
op
if ((store = X509_STORE_new()) == NULL)
186
2021-02-09
op
return NULL;
187
2021-02-09
op
188
2021-02-09
op
if ((f = fopen(path, "r")) == NULL)
189
2021-02-09
op
goto err;
190
2021-02-09
op
191
2021-02-09
op
if ((x = PEM_read_X509(f, NULL, NULL, NULL)) == NULL)
192
2021-02-09
op
goto err;
193
2021-02-09
op
194
2021-02-09
op
if (X509_check_ca(x) == 0)
195
2021-02-09
op
goto err;
196
2021-02-09
op
197
2021-02-09
op
if (!X509_STORE_add_cert(store, x))
198
2021-02-09
op
goto err;
199
2021-02-09
op
200
2021-02-09
op
X509_free(x);
201
2021-02-09
op
fclose(f);
202
2021-02-09
op
return store;
203
2021-02-09
op
204
2021-02-09
op
err:
205
2021-02-09
op
X509_STORE_free(store);
206
2021-02-09
op
if (x != NULL)
207
2021-02-09
op
X509_free(x);
208
2021-02-09
op
if (f != NULL)
209
2021-02-09
op
fclose(f);
210
2021-02-09
op
return NULL;
211
2021-02-09
op
}
212
2021-02-09
op
213
2021-02-09
op
int
214
2021-02-09
op
validate_against_ca(X509_STORE *ca, const uint8_t *chain, size_t len)
215
2021-02-09
op
{
216
2021-02-09
op
X509 *client;
217
2021-02-09
op
BIO *m;
218
2021-02-09
op
X509_STORE_CTX *ctx = NULL;
219
2021-02-09
op
int ret = 0;
220
2021-02-09
op
221
2021-02-09
op
if ((m = BIO_new_mem_buf(chain, len)) == NULL)
222
2021-02-09
op
return 0;
223
2021-02-09
op
224
2021-02-09
op
if ((client = PEM_read_bio_X509(m, NULL, NULL, NULL)) == NULL)
225
2021-02-09
op
goto end;
226
2021-02-09
op
227
2021-02-09
op
if ((ctx = X509_STORE_CTX_new()) == NULL)
228
2021-02-09
op
goto end;
229
2021-02-09
op
230
2021-02-09
op
if (!X509_STORE_CTX_init(ctx, ca, client, NULL))
231
2021-02-09
op
goto end;
232
2021-02-09
op
233
2021-02-09
op
ret = X509_verify_cert(ctx);
234
2021-02-09
op
235
2021-02-09
op
end:
236
2021-02-09
op
BIO_free(m);
237
2021-02-09
op
if (client != NULL)
238
2021-02-09
op
X509_free(client);
239
2021-02-09
op
if (ctx != NULL)
240
2021-02-09
op
X509_STORE_CTX_free(ctx);
241
2021-02-09
op
return ret;
242
2021-03-19
op
}
243
2021-03-19
op
244
2021-03-19
op
void
245
2021-03-19
op
dispatch_imsg(struct imsgbuf *ibuf, imsg_handlerfn **handlers, size_t size)
246
2021-03-19
op
{
247
2021-03-19
op
struct imsg imsg;
248
2021-03-19
op
size_t datalen, i;
249
2021-03-19
op
ssize_t n;
250
2021-03-19
op
251
2021-03-19
op
if ((n = imsg_read(ibuf)) == -1) {
252
2021-03-19
op
if (errno == EAGAIN || errno == EWOULDBLOCK)
253
2021-03-19
op
return;
254
2021-03-19
op
_exit(1);
255
2021-03-19
op
}
256
2021-03-19
op
257
2021-03-19
op
if (n == 0)
258
2021-03-19
op
_exit(1);
259
2021-03-19
op
260
2021-03-19
op
for (;;) {
261
2021-03-19
op
if ((n = imsg_get(ibuf, &imsg)) == -1)
262
2021-03-19
op
_exit(1);
263
2021-03-19
op
if (n == 0)
264
2021-03-19
op
return;
265
2021-03-19
op
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
266
2021-03-19
op
i = imsg.hdr.type;
267
2021-03-19
op
if (i > (size / sizeof(imsg_handlerfn*)) || handlers[i] == NULL)
268
2021-03-19
op
abort();
269
2021-03-19
op
handlers[i](ibuf, &imsg, datalen);
270
2021-03-19
op
imsg_free(&imsg);
271
2021-03-19
op
}
272
2021-02-09
op
}
Omar Polo