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 /* 61 ** TLS_DATA_MD -- calculate MD for data 62 ** 63 ** Parameters: 64 ** buf -- data (in and out!) 65 ** len -- length of data 66 ** md -- digest algorithm 67 ** 68 ** Returns: 69 ** <=0: cert fp calculation failed 70 ** >0: len of fp 71 ** 72 ** Side Effects: 73 ** writes digest to buf 74 */ 75 76 static int 77 tls_data_md(buf, len, md) 78 unsigned char *buf; 79 int len; 80 const EVP_MD *md; 81 { 82 unsigned int md_len; 83 EVP_MD_CTX *mdctx; 84 unsigned char md_buf[EVP_MAX_MD_SIZE]; 85 86 SM_REQUIRE(buf != NULL); 87 SM_REQUIRE(md != NULL); 88 SM_REQUIRE(len >= EVP_MAX_MD_SIZE); 89 90 mdctx = EVP_MD_CTX_create(); 91 if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) 92 return -EINVAL; 93 if (EVP_DigestUpdate(mdctx, (void *)buf, len) != 1) 94 return -EINVAL; 95 if (EVP_DigestFinal_ex(mdctx, md_buf, &md_len) != 1) 96 return -EINVAL; 97 EVP_MD_CTX_destroy(mdctx); 98 99 if (md_len > len) 100 return -ERANGE; 101 (void) memcpy(buf, md_buf, md_len); 102 return (int)md_len; 103 } 104 105 #if DANE 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 return DANE_VRFY_FAIL; 157 len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &end); 158 r = tls_data_md(buf, len, md); 159 if (r < 0) 160 sm_free(buf); 161 else 162 *fp = (char *)buf; 163 return r; 164 } 165 166 /* 167 ** DANE_TLSA_CHK -- check whether a TLSA RR is ok to use 168 ** 169 ** Parameters: 170 ** rr -- RR 171 ** len -- length of RR 172 ** host -- name of host for RR (only for logging) 173 ** log -- whether to log problems 174 ** 175 ** Returns: 176 ** TLSA_*, see tls.h 177 */ 178 179 int 180 dane_tlsa_chk(rr, len, host, log) 181 const char *rr; 182 int len; 183 const char *host; 184 bool log; 185 { 186 int alg; 187 188 if (len < 4) 189 { 190 if (log && LogLevel > 8) 191 sm_syslog(LOG_WARNING, NOQID, 192 "TLSA=%s, len=%d, status=bogus", 193 host, len); 194 return TLSA_BOGUS; 195 } 196 SM_ASSERT(rr != NULL); 197 198 alg = (int)rr[2]; 199 if ((int)rr[0] == 3 && (int)rr[1] == 1 && (alg >= 0 || alg <= 2)) 200 return alg; 201 if (log && LogLevel > 9) 202 sm_syslog(LOG_NOTICE, NOQID, 203 "TLSA=%s, type=%d-%d-%d:%02x, status=unsupported", 204 host, (int)rr[0], (int)rr[1], (int)rr[2], 205 (int)rr[3]); 206 return TLSA_UNSUPP; 207 } 208 209 /* 210 ** DANE_TLSA_CLR -- clear data in a dane_tlsa structure (for use) 211 ** 212 ** Parameters: 213 ** dane_tlsa -- dane_tlsa to clear 214 ** 215 ** Returns: 216 ** 1 if NULL 217 ** 0 if ok 218 */ 219 220 int 221 dane_tlsa_clr(dane_tlsa) 222 dane_tlsa_P dane_tlsa; 223 { 224 int i; 225 226 if (dane_tlsa == NULL) 227 return 1; 228 for (i = 0; i < dane_tlsa->dane_tlsa_n; i++) 229 { 230 SM_FREE(dane_tlsa->dane_tlsa_rr[i]); 231 dane_tlsa->dane_tlsa_len[i] = 0; 232 } 233 SM_FREE(dane_tlsa->dane_tlsa_sni); 234 memset(dane_tlsa, '\0', sizeof(*dane_tlsa)); 235 return 0; 236 237 } 238 239 /* 240 ** DANE_TLSA_FREE -- free a dane_tlsa structure 241 ** 242 ** Parameters: 243 ** dane_tlsa -- dane_tlsa to free 244 ** 245 ** Returns: 246 ** 0 if ok 247 ** 1 if NULL 248 */ 249 250 int 251 dane_tlsa_free(dane_tlsa) 252 dane_tlsa_P dane_tlsa; 253 { 254 if (dane_tlsa == NULL) 255 return 1; 256 dane_tlsa_clr(dane_tlsa); 257 SM_FREE(dane_tlsa); 258 return 0; 259 260 } 261 #endif /* DANE */ 262 263 #endif /* STARTTLS */ 264