|
@@ -39,7 +39,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
39
|
39
|
#include <ipxe/iobuf.h>
|
40
|
40
|
#include <ipxe/xfer.h>
|
41
|
41
|
#include <ipxe/open.h>
|
42
|
|
-#include <ipxe/asn1.h>
|
43
|
42
|
#include <ipxe/x509.h>
|
44
|
43
|
#include <ipxe/rbg.h>
|
45
|
44
|
#include <ipxe/tls.h>
|
|
@@ -90,7 +89,6 @@ static void free_tls ( struct refcnt *refcnt ) {
|
90
|
89
|
tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
|
91
|
90
|
tls_clear_cipher ( tls, &tls->rx_cipherspec );
|
92
|
91
|
tls_clear_cipher ( tls, &tls->rx_cipherspec_pending );
|
93
|
|
- x509_free_rsa_public_key ( &tls->rsa );
|
94
|
92
|
free ( tls->rx_data );
|
95
|
93
|
|
96
|
94
|
/* Free TLS structure itself */
|
|
@@ -437,28 +435,28 @@ struct tls_cipher_suite tls_cipher_suites[] = {
|
437
|
435
|
{
|
438
|
436
|
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ),
|
439
|
437
|
.key_len = ( 256 / 8 ),
|
440
|
|
- .pubkey = &pubkey_null, /* FIXME */
|
|
438
|
+ .pubkey = &rsa_algorithm,
|
441
|
439
|
.cipher = &aes_cbc_algorithm,
|
442
|
440
|
.digest = &sha256_algorithm,
|
443
|
441
|
},
|
444
|
442
|
{
|
445
|
443
|
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ),
|
446
|
444
|
.key_len = ( 128 / 8 ),
|
447
|
|
- .pubkey = &pubkey_null, /* FIXME */
|
|
445
|
+ .pubkey = &rsa_algorithm,
|
448
|
446
|
.cipher = &aes_cbc_algorithm,
|
449
|
447
|
.digest = &sha256_algorithm,
|
450
|
448
|
},
|
451
|
449
|
{
|
452
|
450
|
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ),
|
453
|
451
|
.key_len = ( 256 / 8 ),
|
454
|
|
- .pubkey = &pubkey_null, /* FIXME */
|
|
452
|
+ .pubkey = &rsa_algorithm,
|
455
|
453
|
.cipher = &aes_cbc_algorithm,
|
456
|
454
|
.digest = &sha1_algorithm,
|
457
|
455
|
},
|
458
|
456
|
{
|
459
|
457
|
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ),
|
460
|
458
|
.key_len = ( 128 / 8 ),
|
461
|
|
- .pubkey = &pubkey_null, /* FIXME */
|
|
459
|
+ .pubkey = &rsa_algorithm,
|
462
|
460
|
.cipher = &aes_cbc_algorithm,
|
463
|
461
|
.digest = &sha1_algorithm,
|
464
|
462
|
},
|
|
@@ -496,6 +494,11 @@ tls_find_cipher_suite ( unsigned int cipher_suite ) {
|
496
|
494
|
*/
|
497
|
495
|
static void tls_clear_cipher ( struct tls_session *tls __unused,
|
498
|
496
|
struct tls_cipherspec *cipherspec ) {
|
|
497
|
+
|
|
498
|
+ if ( cipherspec->suite ) {
|
|
499
|
+ pubkey_final ( cipherspec->suite->pubkey,
|
|
500
|
+ cipherspec->pubkey_ctx );
|
|
501
|
+ }
|
499
|
502
|
free ( cipherspec->dynamic );
|
500
|
503
|
memset ( cipherspec, 0, sizeof ( cipherspec ) );
|
501
|
504
|
cipherspec->suite = &tls_cipher_suite_null;
|
|
@@ -523,13 +526,12 @@ static int tls_set_cipher ( struct tls_session *tls,
|
523
|
526
|
|
524
|
527
|
/* Allocate dynamic storage */
|
525
|
528
|
total = ( pubkey->ctxsize + 2 * cipher->ctxsize + digest->digestsize );
|
526
|
|
- dynamic = malloc ( total );
|
|
529
|
+ dynamic = zalloc ( total );
|
527
|
530
|
if ( ! dynamic ) {
|
528
|
531
|
DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto "
|
529
|
532
|
"context\n", tls, total );
|
530
|
533
|
return -ENOMEM;
|
531
|
534
|
}
|
532
|
|
- memset ( dynamic, 0, total );
|
533
|
535
|
|
534
|
536
|
/* Assign storage */
|
535
|
537
|
cipherspec->dynamic = dynamic;
|
|
@@ -793,37 +795,38 @@ static int tls_send_certificate ( struct tls_session *tls ) {
|
793
|
795
|
* @ret rc Return status code
|
794
|
796
|
*/
|
795
|
797
|
static int tls_send_client_key_exchange ( struct tls_session *tls ) {
|
796
|
|
- /* FIXME: Hack alert */
|
797
|
|
- RSA_CTX *rsa_ctx = NULL;
|
798
|
|
- RSA_pub_key_new ( &rsa_ctx, tls->rsa.modulus, tls->rsa.modulus_len,
|
799
|
|
- tls->rsa.exponent, tls->rsa.exponent_len );
|
|
798
|
+ struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
|
|
799
|
+ struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
|
|
800
|
+ size_t max_len = pubkey_max_len ( pubkey, cipherspec->pubkey_ctx );
|
800
|
801
|
struct {
|
801
|
802
|
uint32_t type_length;
|
802
|
803
|
uint16_t encrypted_pre_master_secret_len;
|
803
|
|
- uint8_t encrypted_pre_master_secret[rsa_ctx->num_octets];
|
|
804
|
+ uint8_t encrypted_pre_master_secret[max_len];
|
804
|
805
|
} __attribute__ (( packed )) key_xchg;
|
|
806
|
+ size_t unused;
|
|
807
|
+ int len;
|
|
808
|
+ int rc;
|
805
|
809
|
|
|
810
|
+ /* Encrypt pre-master secret using server's public key */
|
806
|
811
|
memset ( &key_xchg, 0, sizeof ( key_xchg ) );
|
807
|
|
- key_xchg.type_length = ( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) |
|
808
|
|
- htonl ( sizeof ( key_xchg ) -
|
809
|
|
- sizeof ( key_xchg.type_length ) ) );
|
810
|
|
- key_xchg.encrypted_pre_master_secret_len
|
811
|
|
- = htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) );
|
812
|
|
-
|
813
|
|
- /* FIXME: Hack alert */
|
814
|
|
- DBGC ( tls, "RSA encrypting plaintext, modulus, exponent:\n" );
|
815
|
|
- DBGC_HD ( tls, &tls->pre_master_secret,
|
816
|
|
- sizeof ( tls->pre_master_secret ) );
|
817
|
|
- DBGC_HD ( tls, tls->rsa.modulus, tls->rsa.modulus_len );
|
818
|
|
- DBGC_HD ( tls, tls->rsa.exponent, tls->rsa.exponent_len );
|
819
|
|
- RSA_encrypt ( rsa_ctx, ( const uint8_t * ) &tls->pre_master_secret,
|
820
|
|
- sizeof ( tls->pre_master_secret ),
|
821
|
|
- key_xchg.encrypted_pre_master_secret, 0 );
|
822
|
|
- DBGC ( tls, "RSA encrypt done. Ciphertext:\n" );
|
823
|
|
- DBGC_HD ( tls, &key_xchg.encrypted_pre_master_secret,
|
824
|
|
- sizeof ( key_xchg.encrypted_pre_master_secret ) );
|
825
|
|
- RSA_free ( rsa_ctx );
|
826
|
|
-
|
|
812
|
+ len = pubkey_encrypt ( pubkey, cipherspec->pubkey_ctx,
|
|
813
|
+ &tls->pre_master_secret,
|
|
814
|
+ sizeof ( tls->pre_master_secret ),
|
|
815
|
+ key_xchg.encrypted_pre_master_secret );
|
|
816
|
+ if ( len < 0 ) {
|
|
817
|
+ rc = len;
|
|
818
|
+ DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
|
|
819
|
+ tls, strerror ( rc ) );
|
|
820
|
+ return rc;
|
|
821
|
+ }
|
|
822
|
+ unused = ( max_len - len );
|
|
823
|
+ key_xchg.type_length =
|
|
824
|
+ ( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) |
|
|
825
|
+ htonl ( sizeof ( key_xchg ) -
|
|
826
|
+ sizeof ( key_xchg.type_length ) - unused ) );
|
|
827
|
+ key_xchg.encrypted_pre_master_secret_len =
|
|
828
|
+ htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) -
|
|
829
|
+ unused );
|
827
|
830
|
|
828
|
831
|
return tls_send_handshake ( tls, &key_xchg, sizeof ( key_xchg ) );
|
829
|
832
|
}
|
|
@@ -1021,7 +1024,10 @@ static int tls_new_certificate ( struct tls_session *tls,
|
1021
|
1024
|
( ( void * ) certificate->certificates );
|
1022
|
1025
|
size_t elements_len = tls_uint24 ( certificate->length );
|
1023
|
1026
|
const void *end = ( certificate->certificates + elements_len );
|
|
1027
|
+ struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
|
|
1028
|
+ struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
|
1024
|
1029
|
struct asn1_cursor cursor;
|
|
1030
|
+ struct x509_rsa_public_key key;
|
1025
|
1031
|
int rc;
|
1026
|
1032
|
|
1027
|
1033
|
/* Sanity check */
|
|
@@ -1044,12 +1050,20 @@ static int tls_new_certificate ( struct tls_session *tls,
|
1044
|
1050
|
}
|
1045
|
1051
|
|
1046
|
1052
|
// HACK
|
1047
|
|
- if ( ( rc = x509_rsa_public_key ( &cursor,
|
1048
|
|
- &tls->rsa ) ) != 0 ) {
|
1049
|
|
- DBGC ( tls, "TLS %p cannot determine RSA public key: "
|
1050
|
|
- "%s\n", tls, strerror ( rc ) );
|
|
1053
|
+ if ( ( rc = x509_rsa_public_key ( &cursor, &key ) ) != 0 ) {
|
|
1054
|
+ DBGC ( tls, "TLS %p cannot parse public key: %s\n",
|
|
1055
|
+ tls, strerror ( rc ) );
|
|
1056
|
+ return rc;
|
|
1057
|
+ }
|
|
1058
|
+
|
|
1059
|
+ /* Initialise public key algorithm */
|
|
1060
|
+ if ( ( rc = pubkey_init ( pubkey, cipherspec->pubkey_ctx,
|
|
1061
|
+ key.raw.data, key.raw.len ) ) != 0){
|
|
1062
|
+ DBGC ( tls, "TLS %p cannot initialise public key: %s\n",
|
|
1063
|
+ tls, strerror ( rc ) );
|
1051
|
1064
|
return rc;
|
1052
|
1065
|
}
|
|
1066
|
+
|
1053
|
1067
|
return 0;
|
1054
|
1068
|
|
1055
|
1069
|
element = ( cursor.data + cursor.len );
|