1*d2368effSflorian /* $Id: certproc.c,v 1.13 2020/09/14 15:58:50 florian Exp $ */
2de579d12Sflorian /*
3de579d12Sflorian * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv>
4de579d12Sflorian *
5de579d12Sflorian * Permission to use, copy, modify, and distribute this software for any
6de579d12Sflorian * purpose with or without fee is hereby granted, provided that the above
7de579d12Sflorian * copyright notice and this permission notice appear in all copies.
8de579d12Sflorian *
9de579d12Sflorian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
10de579d12Sflorian * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11de579d12Sflorian * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
12de579d12Sflorian * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13de579d12Sflorian * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14de579d12Sflorian * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15de579d12Sflorian * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16de579d12Sflorian */
17de579d12Sflorian
18de579d12Sflorian #include <err.h>
19de579d12Sflorian #include <stdio.h>
20de579d12Sflorian #include <stdlib.h>
21de579d12Sflorian #include <string.h>
22de579d12Sflorian #include <unistd.h>
23de579d12Sflorian
24de579d12Sflorian #include <openssl/pem.h>
25de579d12Sflorian #include <openssl/x509.h>
26de579d12Sflorian #include <openssl/x509v3.h>
27de579d12Sflorian #include <openssl/err.h>
28de579d12Sflorian
29de579d12Sflorian #include "extern.h"
30de579d12Sflorian
31*d2368effSflorian #define BEGIN_MARKER "-----BEGIN CERTIFICATE-----"
32*d2368effSflorian #define END_MARKER "-----END CERTIFICATE-----"
33de579d12Sflorian
34de579d12Sflorian int
certproc(int netsock,int filesock)35de579d12Sflorian certproc(int netsock, int filesock)
36de579d12Sflorian {
377bce6888Sderaadt char *csr = NULL, *chain = NULL, *url = NULL;
387b00f4e9Sflorian char *chaincp;
39de579d12Sflorian size_t csrsz, chainsz;
407b00f4e9Sflorian int rc = 0, cc;
41de579d12Sflorian enum certop op;
42de579d12Sflorian long lval;
43de579d12Sflorian
44ec0d8c8bSderaadt if (pledge("stdio", NULL) == -1) {
45ec0d8c8bSderaadt warn("pledge");
46de579d12Sflorian goto out;
47ec0d8c8bSderaadt }
48de579d12Sflorian
49de579d12Sflorian /* Read what the netproc wants us to do. */
50de579d12Sflorian
51de579d12Sflorian op = CERT__MAX;
527cd8f039Sjsing if ((lval = readop(netsock, COMM_CSR_OP)) == 0)
53de579d12Sflorian op = CERT_STOP;
547cd8f039Sjsing else if (lval == CERT_REVOKE || lval == CERT_UPDATE)
55de579d12Sflorian op = lval;
56de579d12Sflorian
57de579d12Sflorian if (CERT_STOP == op) {
58de579d12Sflorian rc = 1;
59de579d12Sflorian goto out;
60de579d12Sflorian } else if (CERT__MAX == op) {
61de579d12Sflorian warnx("unknown operation from netproc");
62de579d12Sflorian goto out;
63de579d12Sflorian }
64de579d12Sflorian
65de579d12Sflorian /*
66de579d12Sflorian * Pass revocation right through to fileproc.
67de579d12Sflorian * If the reader is terminated, ignore it.
68de579d12Sflorian */
69de579d12Sflorian
70de579d12Sflorian if (CERT_REVOKE == op) {
71de579d12Sflorian if (writeop(filesock, COMM_CHAIN_OP, FILE_REMOVE) >= 0)
72de579d12Sflorian rc = 1;
73de579d12Sflorian goto out;
74de579d12Sflorian }
75de579d12Sflorian
76de579d12Sflorian /*
77de579d12Sflorian * Wait until we receive the DER encoded (signed) certificate
78de579d12Sflorian * from the network process.
79de579d12Sflorian * Then convert the DER encoding into an X509 certificate.
80de579d12Sflorian */
81de579d12Sflorian
827cd8f039Sjsing if ((csr = readbuf(netsock, COMM_CSR, &csrsz)) == NULL)
83de579d12Sflorian goto out;
84de579d12Sflorian
85*d2368effSflorian if (csrsz < strlen(END_MARKER)) {
867b00f4e9Sflorian warnx("invalid cert");
87de579d12Sflorian goto out;
88de579d12Sflorian }
89de579d12Sflorian
90*d2368effSflorian chaincp = strstr(csr, END_MARKER);
91de579d12Sflorian
927b00f4e9Sflorian if (chaincp == NULL) {
937b00f4e9Sflorian warnx("invalid cert");
947b00f4e9Sflorian goto out;
957b00f4e9Sflorian }
96de579d12Sflorian
97*d2368effSflorian chaincp += strlen(END_MARKER);
98*d2368effSflorian
99*d2368effSflorian if ((chaincp = strstr(chaincp, BEGIN_MARKER)) == NULL) {
100*d2368effSflorian warnx("invalid certificate chain");
101*d2368effSflorian goto out;
102*d2368effSflorian }
103*d2368effSflorian
1047b00f4e9Sflorian if ((chain = strdup(chaincp)) == NULL) {
105de579d12Sflorian warn("strdup");
106de579d12Sflorian goto out;
107de579d12Sflorian }
108de579d12Sflorian
1097b00f4e9Sflorian *chaincp = '\0';
1107b00f4e9Sflorian chainsz = strlen(chain);
1117b00f4e9Sflorian csrsz = strlen(csr);
112de579d12Sflorian
113de579d12Sflorian /* Allow reader termination to just push us out. */
114de579d12Sflorian
1157cd8f039Sjsing if ((cc = writeop(filesock, COMM_CHAIN_OP, FILE_CREATE)) == 0)
116de579d12Sflorian rc = 1;
117de579d12Sflorian if (cc <= 0)
118de579d12Sflorian goto out;
1197cd8f039Sjsing if ((cc = writebuf(filesock, COMM_CHAIN, chain, chainsz)) == 0)
120de579d12Sflorian rc = 1;
121de579d12Sflorian if (cc <= 0)
122de579d12Sflorian goto out;
123de579d12Sflorian
1247b00f4e9Sflorian if (writebuf(filesock, COMM_CSR, csr, csrsz) < 0)
125de579d12Sflorian goto out;
126de579d12Sflorian
127de579d12Sflorian rc = 1;
128de579d12Sflorian out:
129de579d12Sflorian close(netsock);
130de579d12Sflorian close(filesock);
131de579d12Sflorian free(csr);
132de579d12Sflorian free(url);
133de579d12Sflorian free(chain);
13434335c11Sjsing return rc;
135de579d12Sflorian }
136