Fixed RSA "i32" PKCS#1 v1.5 signature generation.
[BearSSL] / src / ssl / ssl_hs_client.t0
index 37c554c..4067b4d 100644 (file)
@@ -429,6 +429,21 @@ addr-ctx: hash_id
 : ext-point-format-length ( -- len )
        supported-curves if 6 else 0 then ;
 
 : ext-point-format-length ( -- len )
        supported-curves if 6 else 0 then ;
 
+\ Length of ALPN extension.
+cc: ext-ALPN-length ( -- len ) {
+       size_t u, len;
+
+       if (ENG->protocol_names_num == 0) {
+               T0_PUSH(0);
+               T0_RET();
+       }
+       len = 6;
+       for (u = 0; u < ENG->protocol_names_num; u ++) {
+               len += 1 + strlen(ENG->protocol_names[u]);
+       }
+       T0_PUSH(len);
+}
+
 \ Write handshake message: ClientHello
 : write-ClientHello ( -- )
        { ; total-ext-length }
 \ Write handshake message: ClientHello
 : write-ClientHello ( -- )
        { ; total-ext-length }
@@ -438,6 +453,7 @@ addr-ctx: hash_id
        ext-reneg-length ext-sni-length + ext-frag-length +
        ext-signatures-length +
        ext-supported-curves-length + ext-point-format-length +
        ext-reneg-length ext-sni-length + ext-frag-length +
        ext-signatures-length +
        ext-supported-curves-length + ext-point-format-length +
+       ext-ALPN-length +
        >total-ext-length
 
        \ ClientHello type
        >total-ext-length
 
        \ ClientHello type
@@ -542,6 +558,21 @@ addr-ctx: hash_id
                        0x0002 write16          \ extension length
                        0x0100 write16          \ value: 1 format: uncompressed
                then
                        0x0002 write16          \ extension length
                        0x0100 write16          \ value: 1 format: uncompressed
                then
+               ext-ALPN-length dup if
+                       0x0010 write16          \ extension type (16)
+                       4 - dup write16         \ extension length
+                       2- write16              \ list length
+                       addr-protocol_names_num get16 0
+                       begin
+                               dup2 > while
+                               dup copy-protocol-name
+                               dup write8 addr-pad swap write-blob
+                               1+
+                       repeat
+                       2drop
+               else
+                       drop
+               then
                ext-padding-amount 0< ifnot
                        0x0015 write16          \ extension value (21)
                        ext-padding-amount
                ext-padding-amount 0< ifnot
                        0x0015 write16          \ extension value (21)
                        ext-padding-amount
@@ -595,6 +626,24 @@ addr-ctx: hash_id
                then
        then ;
 
                then
        then ;
 
+\ Read the ALPN extension from the server. It must contain a single name,
+\ and that name must match one of our names.
+: read-ALPN-from-server ( lim -- lim )
+       \ Extension contents length.
+       read16 open-elt
+       \ Length of list of names.
+       read16 open-elt
+       \ There should be a single name.
+       read8 addr-pad swap dup { len } read-blob
+       close-elt
+       close-elt
+       len test-protocol-name dup 0< if
+               3 flag? if ERR_UNEXPECTED fail then
+               drop
+       else
+               1+ addr-selected_protocol set16
+       then ;
+
 \ Save a value in a 16-bit field, or check it in case of session resumption.
 : check-resume ( val addr resume -- )
        if get16 = ifnot ERR_RESUME_MISMATCH fail then else set16 then ;
 \ Save a value in a 16-bit field, or check it in case of session resumption.
 : check-resume ( val addr resume -- )
        if get16 = ifnot ERR_RESUME_MISMATCH fail then else set16 then ;
@@ -688,6 +737,7 @@ cc: DEBUG-BLOB ( addr len -- ) {
                ext-signatures-length { ok-signatures }
                ext-supported-curves-length { ok-curves }
                ext-point-format-length { ok-points }
                ext-signatures-length { ok-signatures }
                ext-supported-curves-length { ok-curves }
                ext-point-format-length { ok-points }
+               ext-ALPN-length { ok-ALPN }
                begin dup while
                        read16
                        case
                begin dup while
                        read16
                        case
@@ -753,6 +803,15 @@ cc: DEBUG-BLOB ( addr len -- ) {
                                        read-ignore-16
                                endof
 
                                        read-ignore-16
                                endof
 
+                               \ ALPN.
+                               0x0010 of
+                                       ok-ALPN ifnot
+                                               ERR_EXTRA_EXTENSION fail
+                                       then
+                                       0 >ok-ALPN
+                                       read-ALPN-from-server
+                               endof
+
                                ERR_EXTRA_EXTENSION fail
                        endcase
                repeat
                                ERR_EXTRA_EXTENSION fail
                        endcase
                repeat
@@ -1102,6 +1161,7 @@ cc: do-client-sign ( -- sig_len ) {
 : do-handshake ( -- )
        0 addr-application_data set8
        22 addr-record_type_out set8
 : do-handshake ( -- )
        0 addr-application_data set8
        22 addr-record_type_out set8
+       0 addr-selected_protocol set16
        multihash-init
 
        write-ClientHello
        multihash-init
 
        write-ClientHello