1 /* 2 * Copyright (c) 2015 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 11 #include <sendmail.h> 12 13 SM_RCSID("@(#)$Id: tls.c,v 8.127 2013-11-27 02:51:11 gshapiro Exp $") 14 15 #if STARTTLS 16 # include <tls.h> 17 18 /* 19 ** DATA2HEX -- create a printable hex string from binary data ("%02X:") 20 ** 21 ** Parameters: 22 ** buf -- data 23 ** len -- length of data 24 ** hex -- output buffer 25 ** hlen -- length of output buffer 26 ** 27 ** Returns: 28 ** <0: errno 29 ** >0: length of data in hex 30 */ 31 32 int 33 data2hex(buf, blen, hex, hlen) 34 unsigned char *buf; 35 int blen; 36 unsigned char *hex; 37 int hlen; 38 { 39 int r, h; 40 static const char hexcodes[] = "0123456789ABCDEF"; 41 42 SM_REQUIRE(buf != NULL); 43 SM_REQUIRE(hex != NULL); 44 if (blen * 3 + 2 > hlen) 45 return -ERANGE; 46 47 for (r = 0, h = 0; r < blen && h + 3 < hlen; r++) 48 { 49 hex[h++] = hexcodes[(buf[r] & 0xf0) >> 4]; 50 hex[h++] = hexcodes[(buf[r] & 0x0f)]; 51 if (r + 1 < blen) 52 hex[h++] = ':'; 53 } 54 if (h >= hlen) 55 return -ERANGE; 56 hex[h] = '\0'; 57 return h; 58 } 59 60 # if DANE 61 62 /* 63 ** TLS_DATA_MD -- calculate MD for data 64 ** 65 ** Parameters: 66 ** buf -- data (in and out!) 67 ** len -- length of data 68 ** md -- digest algorithm 69 ** 70 ** Returns: 71 ** <=0: cert fp calculation failed 72 ** >0: len of fp 73 ** 74 ** Side Effects: 75 ** writes digest to buf 76 */ 77 78 static int 79 tls_data_md(buf, len, md) 80 unsigned char *buf; 81 int len; 82 const EVP_MD *md; 83 { 84 unsigned int md_len; 85 EVP_MD_CTX *mdctx; 86 unsigned char md_buf[EVP_MAX_MD_SIZE]; 87 88 SM_REQUIRE(buf != NULL); 89 SM_REQUIRE(md != NULL); 90 SM_REQUIRE(len >= EVP_MAX_MD_SIZE); 91 92 mdctx = EVP_MD_CTX_create(); 93 if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) 94 return -EINVAL; 95 if (EVP_DigestUpdate(mdctx, (void *)buf, len) != 1) 96 return -EINVAL; 97 if (EVP_DigestFinal_ex(mdctx, md_buf, &md_len) != 1) 98 return -EINVAL; 99 EVP_MD_CTX_destroy(mdctx); 100 101 if (md_len > len) 102 return -ERANGE; 103 (void) memcpy(buf, md_buf, md_len); 104 return (int)md_len; 105 } 106 107 /* 108 ** PUBKEY_FP -- get public key fingerprint 109 ** 110 ** Parameters: 111 ** cert -- TLS cert 112 ** mdalg -- name of digest algorithm 113 ** fp -- (pointer to) fingerprint buffer 114 ** 115 ** Returns: 116 ** <=0: cert fp calculation failed 117 ** >0: len of fp 118 */ 119 120 int 121 pubkey_fp(cert, mdalg, fp) 122 X509 *cert; 123 const char *mdalg; 124 char **fp; 125 { 126 int len, r; 127 unsigned char *buf, *end; 128 const EVP_MD *md; 129 130 SM_ASSERT(cert != NULL); 131 SM_ASSERT(fp != NULL); 132 SM_ASSERT(mdalg != NULL); 133 134 len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL); 135 136 /* what's an acceptable upper limit? */ 137 if (len <= 0 || len >= 8192) 138 return -EINVAL; 139 if (len < EVP_MAX_MD_SIZE) 140 len = EVP_MAX_MD_SIZE; 141 end = buf = sm_malloc(len); 142 if (NULL == buf) 143 return -ENOMEM; 144 145 if ('\0' == mdalg[0]) 146 { 147 r = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &end); 148 if (r <= 0 || r != len) 149 return -EINVAL; 150 *fp = (char *)buf; 151 return len; 152 } 153 154 md = EVP_get_digestbyname(mdalg); 155 if (NULL == md) 156 { 157 SM_FREE(buf); 158 return DANE_VRFY_FAIL; 159 } 160 len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &end); 161 r = tls_data_md(buf, len, md); 162 if (r < 0) 163 sm_free(buf); 164 else 165 *fp = (char *)buf; 166 return r; 167 } 168 169 /* 170 ** DANE_TLSA_CHK -- check whether a TLSA RR is ok to use 171 ** 172 ** Parameters: 173 ** rr -- RR 174 ** len -- length of RR 175 ** host -- name of host for RR (only for logging) 176 ** log -- whether to log problems 177 ** 178 ** Returns: 179 ** TLSA_*, see tls.h 180 */ 181 182 int 183 dane_tlsa_chk(rr, len, host, log) 184 const char *rr; 185 int len; 186 const char *host; 187 bool log; 188 { 189 int alg; 190 191 if (len < 4) 192 { 193 if (log && LogLevel > 8) 194 sm_syslog(LOG_WARNING, NOQID, 195 "TLSA=%s, len=%d, status=bogus", 196 host, len); 197 return TLSA_BOGUS; 198 } 199 SM_ASSERT(rr != NULL); 200 201 alg = (int)rr[2]; 202 if ((int)rr[0] == 3 && (int)rr[1] == 1 && (alg >= 0 && alg <= 2)) 203 return alg; 204 if (log && LogLevel > 9) 205 sm_syslog(LOG_NOTICE, NOQID, 206 "TLSA=%s, type=%d-%d-%d:%02x, status=unsupported", 207 host, (int)rr[0], (int)rr[1], (int)rr[2], 208 (int)rr[3]); 209 return TLSA_UNSUPP; 210 } 211 212 /* 213 ** DANE_TLSA_CLR -- clear data in a dane_tlsa structure (for use) 214 ** 215 ** Parameters: 216 ** dane_tlsa -- dane_tlsa to clear 217 ** 218 ** Returns: 219 ** 1 if NULL 220 ** 0 if ok 221 */ 222 223 int 224 dane_tlsa_clr(dane_tlsa) 225 dane_tlsa_P dane_tlsa; 226 { 227 int i; 228 229 if (dane_tlsa == NULL) 230 return 1; 231 for (i = 0; i < dane_tlsa->dane_tlsa_n; i++) 232 { 233 SM_FREE(dane_tlsa->dane_tlsa_rr[i]); 234 dane_tlsa->dane_tlsa_len[i] = 0; 235 } 236 SM_FREE(dane_tlsa->dane_tlsa_sni); 237 memset(dane_tlsa, '\0', sizeof(*dane_tlsa)); 238 return 0; 239 240 } 241 242 /* 243 ** DANE_TLSA_FREE -- free a dane_tlsa structure 244 ** 245 ** Parameters: 246 ** dane_tlsa -- dane_tlsa to free 247 ** 248 ** Returns: 249 ** 0 if ok 250 ** 1 if NULL 251 */ 252 253 int 254 dane_tlsa_free(dane_tlsa) 255 dane_tlsa_P dane_tlsa; 256 { 257 if (dane_tlsa == NULL) 258 return 1; 259 dane_tlsa_clr(dane_tlsa); 260 SM_FREE(dane_tlsa); 261 return 0; 262 263 } 264 # endif /* DANE */ 265 266 #endif /* STARTTLS */ 267