예제 #1
0
enum ssl_private_key_result_t tls13_prepare_certificate_verify(
    SSL *ssl, int is_first_run) {
  enum ssl_private_key_result_t ret = ssl_private_key_failure;
  uint8_t *msg = NULL;
  size_t msg_len;
  CBB cbb, body;
  CBB_zero(&cbb);

  uint16_t signature_algorithm;
  if (!tls1_choose_signature_algorithm(ssl, &signature_algorithm)) {
    goto err;
  }
  if (!ssl->method->init_message(ssl, &cbb, &body,
                                 SSL3_MT_CERTIFICATE_VERIFY) ||
      !CBB_add_u16(&body, signature_algorithm)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  /* Sign the digest. */
  CBB child;
  const size_t max_sig_len = ssl_private_key_max_signature_len(ssl);
  uint8_t *sig;
  size_t sig_len;
  if (!CBB_add_u16_length_prefixed(&body, &child) ||
      !CBB_reserve(&child, &sig, max_sig_len)) {
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    goto err;
  }

  enum ssl_private_key_result_t sign_result;
  if (is_first_run) {
    if (!tls13_get_cert_verify_signature_input(ssl, &msg, &msg_len,
                                               ssl->server)) {
      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      goto err;
    }
    sign_result = ssl_private_key_sign(ssl, sig, &sig_len, max_sig_len,
                                       signature_algorithm, msg, msg_len);
  } else {
    sign_result = ssl_private_key_complete(ssl, sig, &sig_len, max_sig_len);
  }

  if (sign_result != ssl_private_key_success) {
    ret = sign_result;
    goto err;
  }

  if (!CBB_did_write(&child, sig_len) ||
      !ssl->method->finish_message(ssl, &cbb)) {
    goto err;
  }

  ret = ssl_private_key_success;

err:
  CBB_cleanup(&cbb);
  OPENSSL_free(msg);
  return ret;
}
예제 #2
0
int ssl_private_key_supports_signature_algorithm(SSL *ssl,
                                                 uint16_t signature_algorithm) {
  const EVP_MD *md;
  if (is_rsa_pkcs1(&md, signature_algorithm) &&
      ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
    return ssl_private_key_type(ssl) == NID_rsaEncryption;
  }

  int curve;
  if (is_ecdsa(&curve, &md, signature_algorithm)) {
    int type = ssl_private_key_type(ssl);
    if (!ssl_is_ecdsa_key_type(type)) {
      return 0;
    }

    /* Prior to TLS 1.3, ECDSA curves did not match the signature algorithm. */
    if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
      return 1;
    }

    return curve != NID_undef && type == curve;
  }

  if (is_rsa_pss(&md, signature_algorithm)) {
    if (ssl_private_key_type(ssl) != NID_rsaEncryption) {
      return 0;
    }

    /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
     * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
     * hash in TLS. Reasonable RSA key sizes are large enough for the largest
     * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for
     * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check
     * the size to fall back to another algorithm. */
    if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) {
      return 0;
    }

    /* RSA-PSS is only supported by message-based private keys. */
    if (ssl->cert->key_method != NULL && ssl->cert->key_method->sign == NULL) {
      return 0;
    }

    return 1;
  }

  return 0;
}
예제 #3
0
int ssl_private_key_supports_signature_algorithm(SSL *ssl,
                                                 uint16_t signature_algorithm) {
  const EVP_MD *md;
  if (is_rsa_pkcs1(&md, signature_algorithm)) {
    return ssl_private_key_type(ssl) == EVP_PKEY_RSA;
  }

  int curve;
  if (is_ecdsa(&curve, &md, signature_algorithm)) {
    if (ssl_private_key_type(ssl) != EVP_PKEY_EC) {
      return 0;
    }

    /* For non-custom keys, also check the curve matches. Custom private keys
     * must instead configure the signature algorithms accordingly. */
    if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
        ssl->cert->key_method == NULL) {
      EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey);
      if (curve == NID_undef ||
          EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve) {
        return 0;
      }
    }
    return 1;
  }

  if (is_rsa_pss(&md, signature_algorithm)) {
    if (ssl3_protocol_version(ssl) < TLS1_3_VERSION ||
        ssl_private_key_type(ssl) != EVP_PKEY_RSA) {
      return 0;
    }

    /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
     * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
     * hash in TLS. Reasonable RSA key sizes are large enough for the largest
     * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for
     * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check
     * the size to fall back to another algorithm. */
    if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) {
      return 0;
    }

    return 1;
  }

  return 0;
}