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
tls_data_md(buf,len,md)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 -- generate public key fingerprint
109 **
110 ** Parameters:
111 ** cert -- TLS cert
112 ** mdalg -- name of digest algorithm
113 ** fp -- (pointer to) fingerprint buffer (output)
114 **
115 ** Returns:
116 ** <=0: cert fp calculation failed
117 ** >0: len of fp
118 */
119
120 int
pubkey_fp(cert,mdalg,fp)121 pubkey_fp(cert, mdalg, fp)
122 X509 *cert;
123 const char *mdalg;
124 unsigned char **fp;
125 {
126 int len, r;
127 unsigned char *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 *fp = end = sm_malloc(len);
142 if (NULL == end)
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 return len;
151 }
152
153 md = EVP_get_digestbyname(mdalg);
154 if (NULL == md)
155 {
156 SM_FREE(*fp);
157 return DANE_VRFY_FAIL;
158 }
159 len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &end);
160 r = tls_data_md(*fp, len, md);
161 if (r < 0)
162 sm_free(*fp);
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 ** >=0: "alg" aka "matching type"
177 ** <0: TLSA_*, see tls.h
178 */
179
180 int
dane_tlsa_chk(rr,len,host,log)181 dane_tlsa_chk(rr, len, host, log)
182 const unsigned char *rr;
183 int len;
184 const char *host;
185 bool log;
186 {
187 int alg;
188 # if HAVE_SSL_CTX_dane_enable
189 int sel, usg;
190 # endif
191
192 if (len < 4)
193 {
194 if (log && LogLevel > 8)
195 sm_syslog(LOG_WARNING, NOQID,
196 "TLSA=%s, len=%d, status=bogus",
197 host, len);
198 return TLSA_BOGUS;
199 }
200 SM_ASSERT(rr != NULL);
201
202 alg = (int)rr[2];
203 # if HAVE_SSL_CTX_dane_enable
204 usg = (int)rr[0];
205 sel = (int)rr[1];
206 if (usg >= 2 && usg <= 3 && sel >= 0 && sel <= 1 &&
207 alg >= 0 && alg <= 2)
208 return alg;
209 # else
210 if ((int)rr[0] == 3 && (int)rr[1] == 1 && (alg >= 0 && alg <= 2))
211 return alg;
212 # endif
213 if (log && LogLevel > 9)
214 sm_syslog(LOG_NOTICE, NOQID,
215 "TLSA=%s, type=%d-%d-%d:%02x, status=unsupported",
216 host, (int)rr[0], (int)rr[1], (int)rr[2],
217 (int)rr[3]);
218 return TLSA_UNSUPP;
219 }
220
221 /*
222 ** DANE_TLSA_CLR -- clear data in a dane_tlsa structure (for use)
223 **
224 ** Parameters:
225 ** dane_tlsa -- dane_tlsa to clear
226 **
227 ** Returns:
228 ** 1 if NULL
229 ** 0 if ok
230 */
231
232 int
dane_tlsa_clr(dane_tlsa)233 dane_tlsa_clr(dane_tlsa)
234 dane_tlsa_P dane_tlsa;
235 {
236 int i;
237
238 if (dane_tlsa == NULL)
239 return 1;
240 for (i = 0; i < dane_tlsa->dane_tlsa_n; i++)
241 {
242 SM_FREE(dane_tlsa->dane_tlsa_rr[i]);
243 dane_tlsa->dane_tlsa_len[i] = 0;
244 }
245 SM_FREE(dane_tlsa->dane_tlsa_sni);
246 memset(dane_tlsa, '\0', sizeof(*dane_tlsa));
247 return 0;
248
249 }
250
251 /*
252 ** DANE_TLSA_FREE -- free a dane_tlsa structure
253 **
254 ** Parameters:
255 ** dane_tlsa -- dane_tlsa to free
256 **
257 ** Returns:
258 ** 0 if ok
259 ** 1 if NULL
260 */
261
262 int
dane_tlsa_free(dane_tlsa)263 dane_tlsa_free(dane_tlsa)
264 dane_tlsa_P dane_tlsa;
265 {
266 if (dane_tlsa == NULL)
267 return 1;
268 dane_tlsa_clr(dane_tlsa);
269 SM_FREE(dane_tlsa);
270 return 0;
271
272 }
273 # endif /* DANE */
274
275 #endif /* STARTTLS */
276