+struct ssl_async_args {
+ SSL *s;
+ void *buf;
+ int num;
+ enum { READFUNC, WRITEFUNC, OTHERFUNC} type;
+ union {
+ int (*func_read)(SSL *, void *, int);
+ int (*func_write)(SSL *, const void *, int);
+ int (*func_other)(SSL *);
+ } f;
+};
+
+static const struct {
+ uint8_t mtype;
+ uint8_t ord;
+ int nid;
+} dane_mds[] = {
+ { DANETLS_MATCHING_FULL, 0, NID_undef },
+ { DANETLS_MATCHING_2256, 1, NID_sha256 },
+ { DANETLS_MATCHING_2512, 2, NID_sha512 },
+};
+
+static int dane_ctx_enable(struct dane_ctx_st *dctx)
+{
+ const EVP_MD **mdevp;
+ uint8_t *mdord;
+ uint8_t mdmax = DANETLS_MATCHING_LAST;
+ int n = ((int) mdmax) + 1; /* int to handle PrivMatch(255) */
+ size_t i;
+
+ mdevp = OPENSSL_zalloc(n * sizeof(*mdevp));
+ mdord = OPENSSL_zalloc(n * sizeof(*mdord));
+
+ if (mdord == NULL || mdevp == NULL) {
+ OPENSSL_free(mdevp);
+ SSLerr(SSL_F_DANE_CTX_ENABLE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ /* Install default entries */
+ for (i = 0; i < OSSL_NELEM(dane_mds); ++i) {
+ const EVP_MD *md;
+
+ if (dane_mds[i].nid == NID_undef ||
+ (md = EVP_get_digestbynid(dane_mds[i].nid)) == NULL)
+ continue;
+ mdevp[dane_mds[i].mtype] = md;
+ mdord[dane_mds[i].mtype] = dane_mds[i].ord;
+ }
+
+ dctx->mdevp = mdevp;
+ dctx->mdord = mdord;
+ dctx->mdmax = mdmax;
+
+ return 1;
+}
+
+static void dane_ctx_final(struct dane_ctx_st *dctx)
+{
+ OPENSSL_free(dctx->mdevp);
+ dctx->mdevp = NULL;
+
+ OPENSSL_free(dctx->mdord);
+ dctx->mdord = NULL;
+ dctx->mdmax = 0;
+}
+
+static void tlsa_free(danetls_record *t)
+{
+ if (t == NULL)
+ return;
+ OPENSSL_free(t->data);
+ EVP_PKEY_free(t->spki);
+ OPENSSL_free(t);
+}
+
+static void dane_final(struct dane_st *dane)
+{
+ sk_danetls_record_pop_free(dane->trecs, tlsa_free);
+ dane->trecs = NULL;
+
+ sk_X509_pop_free(dane->certs, X509_free);
+ dane->certs = NULL;
+
+ X509_free(dane->mcert);
+ dane->mcert = NULL;
+ dane->mtlsa = NULL;
+ dane->mdpth = -1;
+ dane->pdpth = -1;
+}
+
+/*
+ * dane_copy - Copy dane configuration, sans verification state.
+ */
+static int ssl_dane_dup(SSL *to, SSL *from)
+{
+ int num;
+ int i;
+
+ if (!DANETLS_ENABLED(&from->dane))
+ return 1;
+
+ dane_final(&to->dane);
+
+ num = sk_danetls_record_num(from->dane.trecs);
+ for (i = 0; i < num; ++i) {
+ danetls_record *t = sk_danetls_record_value(from->dane.trecs, i);
+ if (SSL_dane_tlsa_add(to, t->usage, t->selector, t->mtype,
+ t->data, t->dlen) <= 0)
+ return 0;
+ }
+ return 1;
+}
+
+static int dane_mtype_set(
+ struct dane_ctx_st *dctx,
+ const EVP_MD *md,
+ uint8_t mtype,
+ uint8_t ord)
+{
+ int i;
+
+ if (mtype == DANETLS_MATCHING_FULL && md != NULL) {
+ SSLerr(SSL_F_DANE_MTYPE_SET,
+ SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL);
+ return 0;
+ }
+
+ if (mtype > dctx->mdmax) {
+ const EVP_MD **mdevp;
+ uint8_t *mdord;
+ int n = ((int) mtype) + 1;
+
+ mdevp = OPENSSL_realloc(dctx->mdevp, n * sizeof(*mdevp));
+ if (mdevp == NULL) {
+ SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ dctx->mdevp = mdevp;
+
+ mdord = OPENSSL_realloc(dctx->mdord, n * sizeof(*mdord));
+ if (mdord == NULL) {
+ SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ dctx->mdord = mdord;
+
+ /* Zero-fill any gaps */
+ for (i = dctx->mdmax+1; i < mtype; ++i) {
+ mdevp[i] = NULL;
+ mdord[i] = 0;
+ }
+
+ dctx->mdmax = mtype;
+ }
+
+ dctx->mdevp[mtype] = md;
+ /* Coerce ordinal of disabled matching types to 0 */
+ dctx->mdord[mtype] = (md == NULL) ? 0 : ord;
+
+ return 1;
+}
+
+static const EVP_MD *tlsa_md_get(struct dane_st *dane, uint8_t mtype)
+{
+ if (mtype > dane->dctx->mdmax)
+ return NULL;
+ return dane->dctx->mdevp[mtype];
+}
+
+static int dane_tlsa_add(
+ struct dane_st *dane,
+ uint8_t usage,
+ uint8_t selector,
+ uint8_t mtype,
+ unsigned char *data,
+ size_t dlen)
+{
+ danetls_record *t;
+ const EVP_MD *md = NULL;
+ int ilen = (int)dlen;
+ int i;
+
+ if (dane->trecs == NULL) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_NOT_ENABLED);
+ return -1;
+ }
+
+ if (ilen < 0 || dlen != (size_t)ilen) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DATA_LENGTH);
+ return 0;
+ }
+
+ if (usage > DANETLS_USAGE_LAST) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE);
+ return 0;
+ }
+
+ if (selector > DANETLS_SELECTOR_LAST) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_SELECTOR);
+ return 0;
+ }
+
+ if (mtype != DANETLS_MATCHING_FULL) {
+ md = tlsa_md_get(dane, mtype);
+ if (md == NULL) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE);
+ return 0;
+ }
+ }
+
+ if (md != NULL && dlen != (size_t)EVP_MD_size(md)) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
+ return 0;
+ }
+ if (!data) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_NULL_DATA);
+ return 0;
+ }
+
+ if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ t->usage = usage;
+ t->selector = selector;
+ t->mtype = mtype;
+ t->data = OPENSSL_malloc(ilen);
+ if (t->data == NULL) {
+ tlsa_free(t);
+ SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ memcpy(t->data, data, ilen);
+ t->dlen = ilen;
+
+ /* Validate and cache full certificate or public key */
+ if (mtype == DANETLS_MATCHING_FULL) {
+ const unsigned char *p = data;
+ X509 *cert = NULL;
+ EVP_PKEY *pkey = NULL;
+
+ switch (selector) {
+ case DANETLS_SELECTOR_CERT:
+ if (!d2i_X509(&cert, &p, dlen) || p < data ||
+ dlen != (size_t)(p - data)) {
+ tlsa_free(t);
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
+ return 0;
+ }
+ if (X509_get0_pubkey(cert) == NULL) {
+ tlsa_free(t);
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
+ return 0;
+ }
+
+ if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) {
+ X509_free(cert);
+ break;
+ }
+
+ /*
+ * For usage DANE-TA(2), we support authentication via "2 0 0" TLSA
+ * records that contain full certificates of trust-anchors that are
+ * not present in the wire chain. For usage PKIX-TA(0), we augment
+ * the chain with untrusted Full(0) certificates from DNS, in case
+ * they are missing from the chain.
+ */
+ if ((dane->certs == NULL &&
+ (dane->certs = sk_X509_new_null()) == NULL) ||
+ !sk_X509_push(dane->certs, cert)) {
+ SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+ X509_free(cert);
+ tlsa_free(t);
+ return -1;
+ }
+ break;
+
+ case DANETLS_SELECTOR_SPKI:
+ if (!d2i_PUBKEY(&pkey, &p, dlen) || p < data ||
+ dlen != (size_t)(p - data)) {
+ tlsa_free(t);
+ SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY);
+ return 0;
+ }
+
+ /*
+ * For usage DANE-TA(2), we support authentication via "2 1 0" TLSA
+ * records that contain full bare keys of trust-anchors that are
+ * not present in the wire chain.
+ */
+ if (usage == DANETLS_USAGE_DANE_TA)
+ t->spki = pkey;
+ else
+ EVP_PKEY_free(pkey);
+ break;
+ }
+ }
+
+ /*-
+ * Find the right insertion point for the new record.
+ *
+ * See crypto/x509/x509_vfy.c. We sort DANE-EE(3) records first, so that
+ * they can be processed first, as they require no chain building, and no
+ * expiration or hostname checks. Because DANE-EE(3) is numerically
+ * largest, this is accomplished via descending sort by "usage".
+ *
+ * We also sort in descending order by matching ordinal to simplify
+ * the implementation of digest agility in the verification code.
+ *
+ * The choice of order for the selector is not significant, so we
+ * use the same descending order for consistency.
+ */
+ for (i = 0; i < sk_danetls_record_num(dane->trecs); ++i) {
+ danetls_record *rec = sk_danetls_record_value(dane->trecs, i);
+ if (rec->usage > usage)
+ continue;
+ if (rec->usage < usage)
+ break;
+ if (rec->selector > selector)
+ continue;
+ if (rec->selector < selector)
+ break;
+ if (dane->dctx->mdord[rec->mtype] > dane->dctx->mdord[mtype])
+ continue;
+ break;
+ }
+
+ if (!sk_danetls_record_insert(dane->trecs, t, i)) {
+ tlsa_free(t);
+ SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ dane->umask |= DANETLS_USAGE_BIT(usage);
+
+ return 1;
+}
+
+static void clear_ciphers(SSL *s)
+{
+ /* clear the current cipher */
+ ssl_clear_cipher_ctx(s);
+ ssl_clear_hash_ctx(&s->read_hash);
+ ssl_clear_hash_ctx(&s->write_hash);
+}
+