From e71098a6525c84c37ed1567d6eb8935d39c5c28e Mon Sep 17 00:00:00 2001 From: Derek Pryor Date: Mon, 17 Jul 2006 16:38:20 +0000 Subject: The first packet (ClientHello Handshake) can be constructed and is accepted by SSL servers. Framework.c allows me to test the library against a given https server. --- src/crypto/ssl_constructs.h | 194 +++++++++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 83 deletions(-) (limited to 'src/crypto/ssl_constructs.h') diff --git a/src/crypto/ssl_constructs.h b/src/crypto/ssl_constructs.h index 43c585518..ab3aa7037 100644 --- a/src/crypto/ssl_constructs.h +++ b/src/crypto/ssl_constructs.h @@ -1,4 +1,6 @@ // Note: This file still needs some work. +// Note: I had to redefine the enums to a set of const values, +// so that the size of the variable would be correct. // Typedefs // (As defined by the SSL v3.0 RFC Draft) @@ -14,15 +16,13 @@ typedef struct _ProtocolVersion{ uint8 major, minor; } ProtocolVersion; -ProtocolVersion version = { 3, 0 }; +const ProtocolVersion version = { 3, 0 }; -typedef enum _ContentType{ - content_type_change_cipher_spec_type=20, - content_type_alert=21, - content_type_handshake=22, - content_type_application_data=23, - content_type_size=255 // to force size -} ContentType; +typedef uint8 ContentType; +const ContentType content_type_change_cipher_spec_type = 20; +const ContentType content_type_alert = 21; +const ContentType content_type_handshake = 22; +const ContentType content_type_application_data = 23; typedef struct _SSLPlaintext{ ContentType type; @@ -38,6 +38,14 @@ typedef struct _SSLCompressed{ uint8 fragment[17408]; // SSLCompressed.length } SSLCompressed; +typedef struct _SSLCiphertext{ + ContentType type; + ProtocolVersion version; + uint16 length; + uint8 fragment; // so we have a pointer to the data, and don't have to do math + // fragment; type GenericStreamCipher or GenericBlockCipher +} SSLCiphertext; // recast to get fragment + typedef struct _GenericStreamCipher{ uint8 content[17408]; // SSLCompressed.length uint8 MAC[]; // CipherSpec.hash_size @@ -72,27 +80,23 @@ typedef struct _ChangeCipherSpec{ } ChangeCipherSpec; // Alert messages -typedef enum _AlertLevel{ - alert_level_warning=1, - alert_level_fatal=2, - alert_level_size=255 -} AlertLevel; - -typedef enum _AlertDescription{ - alert_description_close_notify=0, - alert_description_unexpected_message=10, - alert_description_bad_record_mac=20, - alert_description_decompression_failure=30, - alert_description_handshake_failure=40, - alert_description_no_certificate=41, - alert_description_bad_certificate=42, - alert_description_unsupported_certificate=43, - alert_description_certificate_revoked=44, - alert_description_certificate_expired=45, - alert_description_certificate_unknown=46, - alert_description_illegal_parameter=47, - alert_description_size=255 -} AlertDescription; +typedef uint8 AlertLevel; +const AlertLevel alert_level_warning = 1; +const AlertLevel alert_level_fatal=2; + +typedef uint8 AlertDescription; +const AlertDescription alert_description_close_notify = 0; +const AlertDescription alert_description_unexpected_message = 10; +const AlertDescription alert_description_bad_record_mac = 20; +const AlertDescription alert_description_decompression_failure = 30; +const AlertDescription alert_description_handshake_failure = 40; +const AlertDescription alert_description_no_certificate = 41; +const AlertDescription alert_description_bad_certificate = 42; +const AlertDescription alert_description_unsupported_certificate = 43; +const AlertDescription alert_description_certificate_revoked = 44; +const AlertDescription alert_description_certificate_expired = 45; +const AlertDescription alert_description_certificate_unknown = 46; +const AlertDescription alert_description_illegal_parameter = 47; typedef struct _Alert{ AlertLevel level; @@ -101,23 +105,22 @@ typedef struct _Alert{ // Handshake protocol // What is the best way to have a generic pointer to the body struct?? -typedef enum _HandshakeType{ - handshake_type_hello_request=0, - handshake_type_client_hello=1, - handshake_type_server_hello=2, - handshake_type_certificate=11, - handshake_type_server_key_exchange=12, - handshake_type_certificate_request=13, - handshake_type_server_done=14, - handshake_type_certificate_verify=15, - handshake_type_client_key_exchange=16, - handshake_type_finished=20, - handshake_type_size=255 -} HandshakeType; +typedef uint8 HandshakeType; +const HandshakeType handshake_type_hello_request = 0; +const HandshakeType handshake_type_client_hello = 1; +const HandshakeType handshake_type_server_hello = 2; +const HandshakeType handshake_type_certificate = 11; +const HandshakeType handshake_type_server_key_exchange = 12; +const HandshakeType handshake_type_certificate_request = 13; +const HandshakeType handshake_type_server_done = 14; +const HandshakeType handshake_type_certificate_verify = 15; +const HandshakeType handshake_type_client_key_exchange = 16; +const HandshakeType handshake_type_finished = 20; typedef struct _Handshake{ HandshakeType msg_type; uint24 length; + // body; // one of HandshakeType structs } Handshake; // generic Handshake, need to recast to get body // Hello messages @@ -134,21 +137,38 @@ typedef struct _Random{ uint8 random_bytes[28]; } Random; -typedef uint8 SessionID[32]; // <0..32> +//typedef uint8 SessionID[32]; // <0..32> +typedef uint8 SessionIDLength; +typedef uint8 SessionID; + +typedef uint16 CipherSuiteLength; typedef uint8 CipherSuite[2]; -typedef enum _CompressionMethod{ compression_method_null=0, compression_method_size=255 } CompressionMethod; +typedef uint8 CompressionMethodLength; +typedef uint8 CompressionMethod; +const CompressionMethod compression_method_null = 0; + typedef struct _ClientHello{ ProtocolVersion client_version; Random random; - SessionID session_id; - CipherSuite cipher_suites[32768]; // <2..2^16-1> = 65,536 bytes and CipherSuite is 2 bytes - CompressionMethod compression_methods[256]; // <0..2^8-1> = 256 bytes and CompressionMethod is 1 byte + SessionIDLength session_id_length; + SessionID *session_id; + SessionID *session_id_end; + CipherSuiteLength *cipher_suites_length; + CipherSuite *cipher_suites; // min size is one entry + CipherSuite *cipher_suites_end; + //CipherSuite cipher_suites[32768]; // <2..2^16-1> = 65,536 bytes and CipherSuite is 2 bytes + CompressionMethodLength *compression_methods_length; + CompressionMethod *compression_methods; + CompressionMethod *compression_methods_end; + //CompressionMethod *compression_methods; // min size is zero + //CompressionMethod compression_methods[256]; // <0..2^8-1> = 256 bytes and CompressionMethod is 1 byte } ClientHello; typedef struct _ClientHelloHandshake{ - HandshakeType msg_type; + //HandshakeType msg_type; + uint8 msg_type; uint24 length; ClientHello body; } ClientHelloHandshake; @@ -175,11 +195,10 @@ typedef struct _Certificate{ // for some reason the size of certificate_list and ASN1Cert is the same, so only one certificate in the list } Certificate; -typedef enum _KeyExchangeAlgorithm{ - key_exchange_algorithm_rsa, - key_exchange_algorithm_diffie_hellman, - key_exchange_algorithm_fortezza_kea -} KeyExchangeAlgorithm; +typedef uint8 KeyExchangeAlgorithm; +const KeyExchangeAlgorithm key_exchange_algorithm_rsa = 0; +const KeyExchangeAlgorithm key_exchange_algorithm_diffie_hellman = 1; +const KeyExchangeAlgorithm key_exchange_algorithm_fortezza_kea = 2; typedef struct _AnonSignature{ struct {}; @@ -218,22 +237,19 @@ typedef struct _ServerRSAKeyExchange{ Signature signed_params; } ServerRSAKeyExchange; -typedef enum _SignatureAlgorithm{ - signature_algorithm_anonymous, - signature_algorithm_rsa, - signature_algorithm_dsa -} SignatureAlgorithm; - -typedef enum _CertificateType{ - certificate_type_RSA_sign=1, - certificate_type_DSS_sign=2, - certificate_type_RSA_fixed_DH=3, - certificate_type_DSS_fixed_DH=4, - certificate_type_RSA_ephemeral_DH=5, - certificate_type_DSS_ephemeral_DH=6, - certificate_type_FORTEZZA_MISSI=20, - certificate_type_size=255 -} CertificateType; +typedef uint8 SignatureAlgorithm; +const SignatureAlgorithm signature_algorithm_anonymous = 0; +const SignatureAlgorithm signature_algorithm_rsa = 1; +const SignatureAlgorithm signature_algorithm_dsa = 2; + +typedef uint8 CertificateType; +const CertificateType certificate_type_RSA_sign = 1; +const CertificateType certificate_type_DSS_sign = 2; +const CertificateType certificate_type_RSA_fixed_DH = 3; +const CertificateType certificate_type_DSS_fixed_DH = 4; +const CertificateType certificate_type_RSA_ephemeral_DH = 5; +const CertificateType certificate_type_DSS_ephemeral_DH = 6; +const CertificateType certificate_type_FORTEZZA_MISSI = 20; typedef uint8 DistinguishedName[65536]; // <1..2^16-1> = 65,536 @@ -259,7 +275,9 @@ typedef struct _RSAClientKeyExchange{ EncryptedPreMasterSecret exchange_keys; } RSAClientKeyExchange; -typedef enum _PublicValueEncoding{ public_value_encoding_implicit, public_value_encoding_explicit } PublicValueEncoding; +typedef uint8 PublicValueEncoding; +const PublicValueEncoding public_value_encoding_implicit = 0; +const PublicValueEncoding public_value_encoding_explicit = 1; typedef struct _ClientDiffieHellmanPublic{ // This is a select on PublicValueEncoding, and I chose the larger size @@ -281,25 +299,35 @@ typedef struct _Finished{ } Finished; // The CipherSuite -CipherSuite SSL_NULL_WITH_NULL_NULL = { 0x00, 0x00 }; +CipherSuite SSL_NULL_WITH_NULL_NULL = { 0x00, 0x13 }; CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B }; CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C }; +CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 }; CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 }; CipherSuite SSL_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 }; // The CipherSpec -typedef enum _CipherType{ cipher_type_stream, cipher_type_block } CipherType; -typedef enum _IsExportable{ is_exportable_true, is_exportable_false } IsExportable; -typedef enum _BulkCipherAlgorithm{ - bulk_cipher_algorithm_null, - bulk_cipher_algorithm_rc4, - bulk_cipher_algorithm_rc2, - bulk_cipher_algorithm_des, - bulk_cipher_algorithm_3des, - bulk_cipher_algorithm_des40, - bulk_cipher_algorithm_fortezza -} BulkCipherAlgorithm; -typedef enum _MACAlgorithm{ mac_algorithm_null, mac_algorithm_md5, mac_algorithm_sha } MACAlgorithm; +typedef uint8 CipherType; +const CipherType cipher_type_stream = 0; +const CipherType cipher_type_block = 1; + +typedef uint8 IsExportable; +const IsExportable is_exportable_true = 0; +const IsExportable is_exportable_false = 1; + +typedef uint8 BulkCipherAlgorithm; +const BulkCipherAlgorithm bulk_cipher_algorithm_null = 0; +const BulkCipherAlgorithm bulk_cipher_algorithm_rc4 = 1; +const BulkCipherAlgorithm bulk_cipher_algorithm_rc2 = 2; +const BulkCipherAlgorithm bulk_cipher_algorithm_des = 3; +const BulkCipherAlgorithm bulk_cipher_algorithm_3des = 4; +const BulkCipherAlgorithm bulk_cipher_algorithm_des40 = 5; +const BulkCipherAlgorithm bulk_cipher_algorithm_fortezza = 6; + +typedef uint8 MACAlgorithm; +const MACAlgorithm mac_algorithm_null = 0; +const MACAlgorithm mac_algorithm_md5 = 1; +const MACAlgorithm mac_algorithm_sha = 2; typedef struct _CipherSpec{ BulkCipherAlgorithm bulk_cipher_algorithm; -- cgit v1.2.3-55-g7522