1 /* $Id: certproc.c,v 1.12 2019/06/07 08:07:52 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 MARKER "-----END CERTIFICATE-----\n" 32 33 int 34 certproc(int netsock, int filesock) 35 { 36 char *csr = NULL, *chain = NULL, *url = NULL; 37 char *chaincp; 38 size_t csrsz, chainsz; 39 int rc = 0, cc; 40 enum certop op; 41 long lval; 42 43 if (pledge("stdio", NULL) == -1) { 44 warn("pledge"); 45 goto out; 46 } 47 48 /* Read what the netproc wants us to do. */ 49 50 op = CERT__MAX; 51 if ((lval = readop(netsock, COMM_CSR_OP)) == 0) 52 op = CERT_STOP; 53 else if (lval == CERT_REVOKE || lval == CERT_UPDATE) 54 op = lval; 55 56 if (CERT_STOP == op) { 57 rc = 1; 58 goto out; 59 } else if (CERT__MAX == op) { 60 warnx("unknown operation from netproc"); 61 goto out; 62 } 63 64 /* 65 * Pass revocation right through to fileproc. 66 * If the reader is terminated, ignore it. 67 */ 68 69 if (CERT_REVOKE == op) { 70 if (writeop(filesock, COMM_CHAIN_OP, FILE_REMOVE) >= 0) 71 rc = 1; 72 goto out; 73 } 74 75 /* 76 * Wait until we receive the DER encoded (signed) certificate 77 * from the network process. 78 * Then convert the DER encoding into an X509 certificate. 79 */ 80 81 if ((csr = readbuf(netsock, COMM_CSR, &csrsz)) == NULL) 82 goto out; 83 84 if (csrsz < strlen(MARKER)) { 85 warnx("invalid cert"); 86 goto out; 87 } 88 89 chaincp = strstr(csr, MARKER); 90 91 if (chaincp == NULL) { 92 warnx("invalid cert"); 93 goto out; 94 } 95 96 chaincp += strlen(MARKER); 97 if ((chain = strdup(chaincp)) == NULL) { 98 warn("strdup"); 99 goto out; 100 } 101 102 *chaincp = '\0'; 103 chainsz = strlen(chain); 104 csrsz = strlen(csr); 105 106 /* Allow reader termination to just push us out. */ 107 108 if ((cc = writeop(filesock, COMM_CHAIN_OP, FILE_CREATE)) == 0) 109 rc = 1; 110 if (cc <= 0) 111 goto out; 112 if ((cc = writebuf(filesock, COMM_CHAIN, chain, chainsz)) == 0) 113 rc = 1; 114 if (cc <= 0) 115 goto out; 116 117 if (writebuf(filesock, COMM_CSR, csr, csrsz) < 0) 118 goto out; 119 120 rc = 1; 121 out: 122 close(netsock); 123 close(filesock); 124 free(csr); 125 free(url); 126 free(chain); 127 return rc; 128 } 129