126 static const char hexcodes[] =
"0123456789ABCDEF";
128 #define checkok(ret) (ok &= ((ret) ? 1 : 0))
129 #define digest_data(p, l) checkok(EVP_DigestUpdate(mdctx, (char *)(p), (l)))
130 #define digest_object(p) digest_data((p), sizeof(*(p)))
131 #define digest_string(s) digest_data((s), strlen(s)+1)
133 #define digest_dane(dane, memb) do { \
134 if ((dane)->memb != 0) \
135 checkok(digest_tlsa_usage(mdctx, (dane)->memb, #memb)); \
138 #define digest_tlsa_argv(tlsa, memb) do { \
139 if ((tlsa)->memb) { \
140 digest_string(#memb); \
141 for (dgst = (tlsa)->memb->argv; *dgst; ++dgst) \
142 digest_string(*dgst); \
148 static int digest_tlsa_usage(EVP_MD_CTX * mdctx, TLS_TLSA *tlsa,
154 for (digest_string(usage); tlsa; tlsa = tlsa->next) {
155 digest_string(tlsa->mdalg);
156 digest_tlsa_argv(tlsa, pkeys);
157 digest_tlsa_argv(tlsa, certs);
164 char *tls_serverid_digest(
const TLS_CLIENT_START_PROPS *props,
long protomask,
170 unsigned char md_buf[EVP_MAX_MD_SIZE];
186 if ((md = EVP_get_digestbyname(mdalg =
"sha256")) == 0
187 && (md = EVP_get_digestbyname(mdalg = props->mdalg)) == 0)
188 msg_panic(
"digest algorithm \"%s\" not found", mdalg);
191 sslversion = OpenSSL_version_num();
193 mdctx = EVP_MD_CTX_create();
194 checkok(EVP_DigestInit_ex(mdctx, md, NULL));
195 digest_string(props->helo ? props->helo :
"");
196 digest_object(&sslversion);
197 digest_object(&protomask);
198 digest_string(ciphers);
226 digest_dane(props->dane, ta);
228 digest_dane(props->dane, ee);
230 digest_string(
TLS_DANE_BASED(props->tls_level) ? props->host :
"");
232 checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
233 EVP_MD_CTX_destroy(mdctx);
235 msg_fatal(
"error computing %s message digest", mdalg);
238 if (md_len > EVP_MAX_MD_SIZE)
239 msg_panic(
"unexpectedly large %s digest size: %u", mdalg, md_len);
252 result =
vstring_alloc(strlen(props->serverid) + 1 + 2 * md_len);
255 for (i = 0; i < md_len; i++) {
265 char *tls_digest_encode(
const unsigned char *md_buf,
int md_len)
268 char *result =
mymalloc(md_len * 3);
271 if (md_len > EVP_MAX_MD_SIZE || md_len >= INT_MAX / 3)
272 msg_panic(
"unexpectedly large message digest size: %u", md_len);
275 for (i = 0; i < md_len; i++) {
276 result[i * 3] = hexcodes[(md_buf[i] & 0xf0) >> 4U];
277 result[(i * 3) + 1] = hexcodes[(md_buf[i] & 0x0f)];
278 result[(i * 3) + 2] = (i + 1 != md_len) ?
':' :
'\0';
285 char *tls_data_fprint(
const char *buf,
int len,
const char *mdalg)
289 unsigned char md_buf[EVP_MAX_MD_SIZE];
294 if ((md = EVP_get_digestbyname(mdalg)) == 0)
295 msg_panic(
"digest algorithm \"%s\" not found", mdalg);
297 mdctx = EVP_MD_CTX_create();
298 checkok(EVP_DigestInit_ex(mdctx, md, NULL));
299 digest_data(buf, len);
300 checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
301 EVP_MD_CTX_destroy(mdctx);
303 msg_fatal(
"error computing %s message digest", mdalg);
305 return (tls_digest_encode(md_buf, md_len));
310 char *tls_cert_fprint(X509 *peercert,
const char *mdalg)
317 len = i2d_X509(peercert, NULL);
319 i2d_X509(peercert, (
unsigned char **) &buf2);
320 if (buf2 - buf != len)
321 msg_panic(
"i2d_X509 invalid result length");
323 result = tls_data_fprint(buf, len, mdalg);
331 char *tls_pkey_fprint(X509 *peercert,
const char *mdalg)
334 const char *myname =
"tls_pkey_fprint";
335 ASN1_BIT_STRING *key;
338 key = X509_get0_pubkey_bitstr(peercert);
340 msg_fatal(
"%s: error extracting legacy public-key fingerprint: %m",
343 result = tls_data_fprint((
char *) key->data, key->length, mdalg);
351 len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), NULL);
353 i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), (
unsigned char **) &buf2);
354 if (buf2 - buf != len)
355 msg_panic(
"i2d_X509_PUBKEY invalid result length");
357 result = tls_data_fprint(buf, len, mdalg);
NORETURN msg_panic(const char *fmt,...)
#define TLS_DANE_BASED(l)
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
#define VSTRING_TERMINATE(vp)
#define VSTRING_ADDCH(vp, ch)
bool var_tls_bc_pkey_fprint
VSTRING * vstring_alloc(ssize_t len)
NORETURN msg_fatal(const char *fmt,...)
char * vstring_export(VSTRING *vp)
void * mymalloc(ssize_t len)