|
@@ -842,6 +842,47 @@ static int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct,
|
|
|
|
|
|
hpos = hash;
|
|
|
|
|
|
+#ifdef CONFIG_TLSV12
|
|
|
+ if (conn->rl.tls_version == TLS_VERSION_1_2) {
|
|
|
+ /*
|
|
|
+ * RFC 5246, 4.7:
|
|
|
+ * TLS v1.2 adds explicit indication of the used signature and
|
|
|
+ * hash algorithms.
|
|
|
+ *
|
|
|
+ * struct {
|
|
|
+ * HashAlgorithm hash;
|
|
|
+ * SignatureAlgorithm signature;
|
|
|
+ * } SignatureAndHashAlgorithm;
|
|
|
+ */
|
|
|
+ if (end - pos < 2) {
|
|
|
+ tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
+ TLS_ALERT_DECODE_ERROR);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (pos[0] != TLS_HASH_ALG_SHA256 ||
|
|
|
+ pos[1] != TLS_SIGN_ALG_RSA) {
|
|
|
+ wpa_printf(MSG_DEBUG, "TLSv1.2: Unsupported hash(%u)/"
|
|
|
+ "signature(%u) algorithm",
|
|
|
+ pos[0], pos[1]);
|
|
|
+ tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
+ TLS_ALERT_INTERNAL_ERROR);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ pos += 2;
|
|
|
+
|
|
|
+ hlen = SHA256_MAC_LEN;
|
|
|
+ if (conn->verify.sha256_cert == NULL ||
|
|
|
+ crypto_hash_finish(conn->verify.sha256_cert, hpos, &hlen) <
|
|
|
+ 0) {
|
|
|
+ conn->verify.sha256_cert = NULL;
|
|
|
+ tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
+ TLS_ALERT_INTERNAL_ERROR);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ conn->verify.sha256_cert = NULL;
|
|
|
+ } else {
|
|
|
+#endif /* CONFIG_TLSV12 */
|
|
|
+
|
|
|
if (alg == SIGN_ALG_RSA) {
|
|
|
hlen = MD5_MAC_LEN;
|
|
|
if (conn->verify.md5_cert == NULL ||
|
|
@@ -872,6 +913,10 @@ static int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct,
|
|
|
if (alg == SIGN_ALG_RSA)
|
|
|
hlen += MD5_MAC_LEN;
|
|
|
|
|
|
+#ifdef CONFIG_TLSV12
|
|
|
+ }
|
|
|
+#endif /* CONFIG_TLSV12 */
|
|
|
+
|
|
|
wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen);
|
|
|
|
|
|
if (end - pos < 2) {
|
|
@@ -911,6 +956,41 @@ static int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct,
|
|
|
wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Decrypted Signature",
|
|
|
buf, buflen);
|
|
|
|
|
|
+#ifdef CONFIG_TLSV12
|
|
|
+ if (conn->rl.tls_version >= TLS_VERSION_1_2) {
|
|
|
+ /*
|
|
|
+ * RFC 3447, A.2.4 RSASSA-PKCS1-v1_5
|
|
|
+ *
|
|
|
+ * DigestInfo ::= SEQUENCE {
|
|
|
+ * digestAlgorithm DigestAlgorithm,
|
|
|
+ * digest OCTET STRING
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * SHA-256 OID: sha256WithRSAEncryption ::= {pkcs-1 11}
|
|
|
+ *
|
|
|
+ * DER encoded DigestInfo for SHA256 per RFC 3447:
|
|
|
+ * 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 ||
|
|
|
+ * H
|
|
|
+ */
|
|
|
+ if (buflen >= 19 + 32 &&
|
|
|
+ os_memcmp(buf, "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01"
|
|
|
+ "\x65\x03\x04\x02\x01\x05\x00\x04\x20", 19) == 0)
|
|
|
+ {
|
|
|
+ wpa_printf(MSG_DEBUG, "TLSv1.2: DigestAlgorithn = "
|
|
|
+ "SHA-256");
|
|
|
+ os_memmove(buf, buf + 19, buflen - 19);
|
|
|
+ buflen -= 19;
|
|
|
+ } else {
|
|
|
+ wpa_printf(MSG_DEBUG, "TLSv1.2: Unrecognized "
|
|
|
+ "DigestInfo");
|
|
|
+ os_free(buf);
|
|
|
+ tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
+ TLS_ALERT_DECRYPT_ERROR);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif /* CONFIG_TLSV12 */
|
|
|
+
|
|
|
if (buflen != hlen || os_memcmp(buf, hash, buflen) != 0) {
|
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in "
|
|
|
"CertificateVerify - did not match with calculated "
|