Remove JPAKE
[openssl.git] / apps / s_cb.c
index 2a18f74dc3034d602ff69b606ae917930c1d1073..a463dac4ffb66c3f43d7552a215e7f3a81b65083 100644 (file)
@@ -131,8 +131,8 @@ int verify_depth = 0;
 int verify_quiet = 0;
 int verify_error = X509_V_OK;
 int verify_return_error = 0;
-unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
-int cookie_initialized = 0;
+static unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
+static int cookie_initialized = 0;
 
 static const char *lookup(int val, const STRINT_PAIR* list, const char* def)
 {
@@ -167,7 +167,7 @@ int verify_callback(int ok, X509_STORE_CTX *ctx)
         if (verify_depth >= depth) {
             if (!verify_return_error)
                 ok = 1;
-            verify_error = X509_V_OK;
+            verify_error = err;
         } else {
             ok = 0;
             verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
@@ -596,6 +596,7 @@ static STRINT_PAIR handshakes[] = {
     {", ClientHello", 1},
     {", ServerHello", 2},
     {", HelloVerifyRequest", 3},
+    {", NewSessionTicket", 4},
     {", Certificate", 11},
     {", ServerKeyExchange", 12},
     {", CertificateRequest", 13},
@@ -603,6 +604,9 @@ static STRINT_PAIR handshakes[] = {
     {", CertificateVerify", 15},
     {", ClientKeyExchange", 16},
     {", Finished", 20},
+    {", CertificateUrl", 21},
+    {", CertificateStatus", 22},
+    {", SupplementalData", 23},
     {NULL}
 };
 
@@ -645,6 +649,9 @@ void msg_cb(int write_p, int version, int content_type, const void *buf,
             if (len > 0)
                 str_details1 = lookup((int)bp[0], handshakes, "???");
             break;
+        case 23:
+            str_content_type = "ApplicationData";
+            break;
 #ifndef OPENSSL_NO_HEARTBEATS
         case 24:
             str_details1 = ", Heartbeat";
@@ -710,34 +717,36 @@ static STRINT_PAIR tlsext_types[] = {
 #endif
 #ifdef TLSEXT_TYPE_encrypt_then_mac
     {"encrypt-then-mac", TLSEXT_TYPE_encrypt_then_mac},
+#endif
+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
+    {"application layer protocol negotiation",
+     TLSEXT_TYPE_application_layer_protocol_negotiation},
+#endif
+#ifdef TLSEXT_TYPE_extended_master_secret
+    {"extended master secret", TLSEXT_TYPE_extended_master_secret},
 #endif
     {NULL}
 };
 
 void tlsext_cb(SSL *s, int client_server, int type,
-               unsigned char *data, int len, void *arg)
+               const unsigned char *data, int len, void *arg)
 {
     BIO *bio = arg;
     const char *extname = lookup(type, tlsext_types, "unknown");
 
     BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
                client_server ? "server" : "client", extname, type, len);
-    BIO_dump(bio, (char *)data, len);
+    BIO_dump(bio, (const char *)data, len);
     (void)BIO_flush(bio);
 }
 
 int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
                              unsigned int *cookie_len)
 {
-    unsigned char *buffer, result[EVP_MAX_MD_SIZE];
-    unsigned int length, resultlength;
-    union {
-        struct sockaddr sa;
-        struct sockaddr_in s4;
-#if OPENSSL_USE_IPV6
-        struct sockaddr_in6 s6;
-#endif
-    } peer;
+    unsigned char *buffer;
+    size_t length;
+    unsigned short port;
+    BIO_ADDR *peer = NULL;
 
     /* Initialize a random secret */
     if (!cookie_initialized) {
@@ -748,120 +757,46 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
         cookie_initialized = 1;
     }
 
+    peer = BIO_ADDR_new();
+    if (peer == NULL) {
+        BIO_printf(bio_err, "memory full\n");
+        return 0;
+    }
+
     /* Read peer information */
-    (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
+    (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), peer);
 
     /* Create buffer with peer's address and port */
-    length = 0;
-    switch (peer.sa.sa_family) {
-    case AF_INET:
-        length += sizeof(struct in_addr);
-        length += sizeof(peer.s4.sin_port);
-        break;
-#if OPENSSL_USE_IPV6
-    case AF_INET6:
-        length += sizeof(struct in6_addr);
-        length += sizeof(peer.s6.sin6_port);
-        break;
-#endif
-    default:
-        OPENSSL_assert(0);
-        break;
-    }
+    BIO_ADDR_rawaddress(peer, NULL, &length);
+    OPENSSL_assert(length != 0);
+    port = BIO_ADDR_rawport(peer);
+    length += sizeof(port);
     buffer = app_malloc(length, "cookie generate buffer");
 
-    switch (peer.sa.sa_family) {
-    case AF_INET:
-        memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
-        memcpy(buffer + sizeof(peer.s4.sin_port),
-               &peer.s4.sin_addr, sizeof(struct in_addr));
-        break;
-#if OPENSSL_USE_IPV6
-    case AF_INET6:
-        memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
-        memcpy(buffer + sizeof(peer.s6.sin6_port),
-               &peer.s6.sin6_addr, sizeof(struct in6_addr));
-        break;
-#endif
-    default:
-        OPENSSL_assert(0);
-        break;
-    }
+    memcpy(buffer, &port, sizeof(port));
+    BIO_ADDR_rawaddress(peer, buffer + sizeof(port), NULL);
 
     /* Calculate HMAC of buffer using the secret */
     HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
-         buffer, length, result, &resultlength);
-    OPENSSL_free(buffer);
+         buffer, length, cookie, cookie_len);
 
-    memcpy(cookie, result, resultlength);
-    *cookie_len = resultlength;
+    OPENSSL_free(buffer);
+    BIO_ADDR_free(peer);
 
     return 1;
 }
 
-int verify_cookie_callback(SSL *ssl, unsigned char *cookie,
+int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
                            unsigned int cookie_len)
 {
-    unsigned char *buffer, result[EVP_MAX_MD_SIZE];
-    unsigned int length, resultlength;
-    union {
-        struct sockaddr sa;
-        struct sockaddr_in s4;
-#if OPENSSL_USE_IPV6
-        struct sockaddr_in6 s6;
-#endif
-    } peer;
-
-    /* If secret isn't initialized yet, the cookie can't be valid */
-    if (!cookie_initialized)
-        return 0;
-
-    /* Read peer information */
-    (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
-
-    /* Create buffer with peer's address and port */
-    length = 0;
-    switch (peer.sa.sa_family) {
-    case AF_INET:
-        length += sizeof(struct in_addr);
-        length += sizeof(peer.s4.sin_port);
-        break;
-#if OPENSSL_USE_IPV6
-    case AF_INET6:
-        length += sizeof(struct in6_addr);
-        length += sizeof(peer.s6.sin6_port);
-        break;
-#endif
-    default:
-        OPENSSL_assert(0);
-        break;
-    }
-    buffer = app_malloc(length, "cookie verify buffer");
-
-    switch (peer.sa.sa_family) {
-    case AF_INET:
-        memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
-        memcpy(buffer + sizeof(peer.s4.sin_port),
-               &peer.s4.sin_addr, sizeof(struct in_addr));
-        break;
-#if OPENSSL_USE_IPV6
-    case AF_INET6:
-        memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
-        memcpy(buffer + sizeof(peer.s6.sin6_port),
-               &peer.s6.sin6_addr, sizeof(struct in6_addr));
-        break;
-#endif
-    default:
-        OPENSSL_assert(0);
-        break;
-    }
-
-    /* Calculate HMAC of buffer using the secret */
-    HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
-         buffer, length, result, &resultlength);
-    OPENSSL_free(buffer);
-
-    if (cookie_len == resultlength
+    unsigned char result[EVP_MAX_MD_SIZE];
+    unsigned int resultlength;
+
+    /* Note: we check cookie_initialized because if it's not,
+     * it cannot be valid */
+    if (cookie_initialized
+        && generate_cookie_callback(ssl, result, &resultlength)
+        && cookie_len == resultlength
         && memcmp(result, cookie, resultlength) == 0)
         return 1;
 
@@ -896,7 +831,7 @@ static STRINT_PAIR chain_flags[] = {
     {"CA signature", CERT_PKEY_CA_SIGNATURE},
     {"EE key parameters", CERT_PKEY_EE_PARAM},
     {"CA key parameters", CERT_PKEY_CA_PARAM},
-    {"Explicity sign with EE key", CERT_PKEY_EXPLICIT_SIGN},
+    {"Explicitly sign with EE key", CERT_PKEY_EXPLICIT_SIGN},
     {"Issuer Name", CERT_PKEY_ISSUER_NAME},
     {"Certificate Type", CERT_PKEY_CERT_TYPE},
     {NULL}
@@ -987,14 +922,7 @@ static int ssl_excert_prepend(SSL_EXCERT **pexc)
 {
     SSL_EXCERT *exc = app_malloc(sizeof(*exc), "prepend cert");
 
-    exc->certfile = NULL;
-    exc->keyfile = NULL;
-    exc->chainfile = NULL;
-    exc->cert = NULL;
-    exc->key = NULL;
-    exc->chain = NULL;
-    exc->prev = NULL;
-    exc->build_chain = 0;
+    memset(exc, 0, sizeof(*exc));
 
     exc->next = *pexc;
     *pexc = exc;
@@ -1057,9 +985,8 @@ int load_excert(SSL_EXCERT **pexc)
         if (!exc->key)
             return 0;
         if (exc->chainfile) {
-            exc->chain = load_certs(exc->chainfile, FORMAT_PEM,
-                                    NULL, NULL, "Server Chain");
-            if (!exc->chain)
+            if (!load_certs(exc->chainfile, &exc->chain, FORMAT_PEM, NULL,
+                            NULL, "Server Chain"))
                 return 0;
         }
     }
@@ -1159,6 +1086,80 @@ static void print_raw_cipherlist(SSL *s)
     BIO_puts(bio_err, "\n");
 }
 
+/*
+ * Hex encoder for TLSA RRdata, not ':' delimited.
+ */
+static char *hexencode(const unsigned char *data, size_t len)
+{
+    static const char *hex = "0123456789abcdef";
+    char *out;
+    char *cp;
+    size_t outlen = 2 * len + 1;
+    int ilen = (int) outlen;
+
+    if (outlen < len || ilen < 0 || outlen != (size_t)ilen) {
+        BIO_printf(bio_err, "%s: %" PRIu64 "-byte buffer too large to hexencode\n",
+                   opt_getprog(), (uint64_t)len);
+        exit(1);
+    }
+    cp = out = app_malloc(ilen, "TLSA hex data buffer");
+
+    while (ilen-- > 0) {
+        *cp++ = hex[(*data >> 4) & 0x0f];
+        *cp++ = hex[*data++ & 0x0f];
+    }
+    *cp = '\0';
+    return out;
+}
+
+void print_verify_detail(SSL *s, BIO *bio)
+{
+    int mdpth;
+    EVP_PKEY *mspki;
+    long verify_err = SSL_get_verify_result(s);
+
+    if (verify_err == X509_V_OK) {
+        const char *peername = SSL_get0_peername(s);
+
+        BIO_printf(bio, "Verification: OK\n");
+        if (peername != NULL)
+            BIO_printf(bio, "Verified peername: %s\n", peername);
+    } else {
+        const char *reason = X509_verify_cert_error_string(verify_err);
+
+        BIO_printf(bio, "Verification error: %s\n", reason);
+    }
+
+    if ((mdpth = SSL_get0_dane_authority(s, NULL, &mspki)) >= 0) {
+        uint8_t usage, selector, mtype;
+        const unsigned char *data = NULL;
+        size_t dlen = 0;
+        char *hexdata;
+
+        mdpth = SSL_get0_dane_tlsa(s, &usage, &selector, &mtype, &data, &dlen);
+
+        /*
+         * The TLSA data field can be quite long when it is a certificate,
+         * public key or even a SHA2-512 digest.  Because the initial octets of
+         * ASN.1 certificates and public keys contain mostly boilerplate OIDs
+         * and lengths, we show the last 12 bytes of the data instead, as these
+         * are more likely to distinguish distinct TLSA records.
+         */
+#define TLSA_TAIL_SIZE 12
+        if (dlen > TLSA_TAIL_SIZE)
+            hexdata = hexencode(data + dlen - TLSA_TAIL_SIZE, TLSA_TAIL_SIZE);
+        else
+            hexdata = hexencode(data, dlen);
+        BIO_printf(bio, "DANE TLSA %d %d %d %s%s %s at depth %d\n",
+                   usage, selector, mtype,
+                   (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata,
+                   (mspki != NULL) ? "signed the certificate" :
+                   mdpth ? "matched TA certificate" : "matched EE certificate",
+                   mdpth);
+        OPENSSL_free(hexdata);
+    }
+}
+
 void print_ssl_summary(SSL *s)
 {
     const SSL_CIPHER *c;
@@ -1173,12 +1174,14 @@ void print_ssl_summary(SSL *s)
     peer = SSL_get_peer_certificate(s);
     if (peer) {
         int nid;
+
         BIO_puts(bio_err, "Peer certificate: ");
         X509_NAME_print_ex(bio_err, X509_get_subject_name(peer),
                            0, XN_FLAG_ONELINE);
         BIO_puts(bio_err, "\n");
         if (SSL_get_peer_signature_nid(s, &nid))
             BIO_printf(bio_err, "Hash used: %s\n", OBJ_nid2sn(nid));
+        print_verify_detail(s, bio_err);
     } else
         BIO_puts(bio_err, "No peer certificate\n");
     X509_free(peer);
@@ -1195,7 +1198,7 @@ void print_ssl_summary(SSL *s)
 }
 
 int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str,
-               SSL_CTX *ctx, int no_ecdhe, int no_jpake)
+               SSL_CTX *ctx)
 {
     int i;
 
@@ -1203,15 +1206,6 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str,
     for (i = 0; i < sk_OPENSSL_STRING_num(str); i += 2) {
         const char *flag = sk_OPENSSL_STRING_value(str, i);
         const char *arg = sk_OPENSSL_STRING_value(str, i + 1);
-        /* If no_ecdhe or named curve already specified don't need a default. */
-        if (!no_ecdhe && strcmp(flag, "-named_curve") == 0)
-            no_ecdhe = 1;
-#ifndef OPENSSL_NO_JPAKE
-        if (!no_jpake && (strcmp(flag, "-cipher") == 0)) {
-            BIO_puts(bio_err, "JPAKE sets cipher to PSK\n");
-            return 0;
-        }
-#endif
         if (SSL_CONF_cmd(cctx, flag, arg) <= 0) {
             if (arg)
                 BIO_printf(bio_err, "Error with command: \"%s %s\"\n",
@@ -1222,27 +1216,6 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str,
             return 0;
         }
     }
-    /*
-     * This is a special case to keep existing s_server functionality: if we
-     * don't have any curve specified *and* we haven't disabled ECDHE then
-     * use P-256.
-     */
-    if (!no_ecdhe) {
-        if (SSL_CONF_cmd(cctx, "-named_curve", "P-256") <= 0) {
-            BIO_puts(bio_err, "Error setting EC curve\n");
-            ERR_print_errors(bio_err);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_JPAKE
-    if (!no_jpake) {
-        if (SSL_CONF_cmd(cctx, "-cipher", "PSK") <= 0) {
-            BIO_puts(bio_err, "Error setting cipher to PSK\n");
-            ERR_print_errors(bio_err);
-            return 0;
-        }
-    }
-#endif
     if (!SSL_CONF_CTX_finish(cctx)) {
         BIO_puts(bio_err, "Error finishing context\n");
         ERR_print_errors(bio_err);
@@ -1279,8 +1252,10 @@ int ssl_load_stores(SSL_CTX *ctx,
 {
     X509_STORE *vfy = NULL, *ch = NULL;
     int rv = 0;
-    if (vfyCApath || vfyCAfile) {
+    if (vfyCApath != NULL || vfyCAfile != NULL) {
         vfy = X509_STORE_new();
+        if (vfy == NULL)
+            goto err;
         if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath))
             goto err;
         add_crls_store(vfy, crls);
@@ -1288,8 +1263,10 @@ int ssl_load_stores(SSL_CTX *ctx,
         if (crl_download)
             store_setup_crl_download(vfy);
     }
-    if (chCApath || chCAfile) {
+    if (chCApath != NULL || chCAfile != NULL) {
         ch = X509_STORE_new();
+        if (ch == NULL)
+            goto err;
         if (!X509_STORE_load_locations(ch, chCAfile, chCApath))
             goto err;
         SSL_CTX_set1_chain_cert_store(ctx, ch);
@@ -1384,26 +1361,26 @@ static int security_callback_debug(SSL *s, SSL_CTX *ctx,
         }
         break;
 #endif
-
+#ifndef OPENSSL_NO_DH
     case SSL_SECOP_OTHER_DH:
         {
             DH *dh = other;
             BIO_printf(sdb->out, "%d", BN_num_bits(dh->p));
             break;
         }
+#endif
     case SSL_SECOP_OTHER_CERT:
         {
             if (cert_md) {
                 int sig_nid = X509_get_signature_nid(other);
                 BIO_puts(sdb->out, OBJ_nid2sn(sig_nid));
             } else {
-                EVP_PKEY *pkey = X509_get_pubkey(other);
+                EVP_PKEY *pkey = X509_get0_pubkey(other);
                 const char *algname = "";
                 EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL,
                                         &algname, EVP_PKEY_get0_asn1(pkey));
                 BIO_printf(sdb->out, "%s, bits=%d",
                            algname, EVP_PKEY_bits(pkey));
-                EVP_PKEY_free(pkey);
             }
             break;
         }