Cryptography Reference
In-Depth Information
if ( parameters->server_public_key.algorithm == rsa )
{
unsigned char *decrypted_signature;
int decrypted_signature_length;
struct asn1struct rsa_signature;
decrypted_signature_length = rsa_decrypt( signature, signature_len,
&decrypted_signature,
&parameters->server_public_key.rsa_public_key );
// TLS 1.2; no longer includes MD-5, just SHA-256,
// but the RSA signature also includes the signature scheme,
// so must be DER-decoded
asn1parse( decrypted_signature, decrypted_signature_length,
&rsa_signature );
if ( memcmp( sha_digest.hash, rsa_signature.children->next->data,
SHA256_BYTE_SIZE ) )
{
asn1free( &rsa_signature );
free( decrypted_signature );
return 0;
}
asn1free( &rsa_signature );
free( decrypted_signature );
}
Notice that the MD5 computation has been removed here; it's no longer needed.
The implementation in Listing 9-8 also completely ignores the declared hash
algorithm; it's included as an OID as the fi rst child of the top-level structure.
The implementation ought to verify that the declared hash algorithm is SHA-
256 and, in theory, compute a separate hash if it isn't. Because no other hash
algorithms are supported here, this check is omitted. If the server gives back,
say, SHA-384, the hashes don't match and an alert is thrown.
The signature structures also prepend the signature and hash algorithms, but
they don't do so as full-blown X.509 OIDs (fortunately). Instead, an enumeration
of supported algorithms is declared as shown in Listing 9-9.
Listing 9-9: “tls.h” signature and hash algorithms
typedef enum
{
none = 0,
md5 = 1,
sha1 = 2,
sha224 = 3,
sha256 = 4,
sha384 = 5,
sha512 = 6
 
Search WWH ::




Custom Search