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