diff options
author | lloyd <[email protected]> | 2012-01-22 01:50:19 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-01-22 01:50:19 +0000 |
commit | e0065f2af522b9573aaf364391139ac12e77eecb (patch) | |
tree | 3a673666026c4345c39558a7c235e78a1aca9d24 /src | |
parent | 8566e2784dc83c6d8c02de42cf2448cb408100f1 (diff) |
Basic outline of the supported curves extension from RFC 4492
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/tls_extensions.cpp | 156 | ||||
-rw-r--r-- | src/tls/tls_extensions.h | 25 |
2 files changed, 167 insertions, 14 deletions
diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 099bdfde6..d9351fdb1 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -17,20 +17,32 @@ TLS_Extension* make_extension(TLS_Data_Reader& reader, u16bit code, u16bit size) { - if(code == TLSEXT_SERVER_NAME_INDICATION) - return new Server_Name_Indicator(reader, size); - else if(code == TLSEXT_MAX_FRAGMENT_LENGTH) - return new Maximum_Fragment_Length(reader, size); - else if(code == TLSEXT_SRP_IDENTIFIER) - return new SRP_Identifier(reader, size); - else if(code == TLSEXT_SAFE_RENEGOTIATION) - return new Renegotation_Extension(reader, size); - else if(code == TLSEXT_SIGNATURE_ALGORITHMS) - return new Signature_Algorithms(reader, size); - else if(code == TLSEXT_NEXT_PROTOCOL) - return new Next_Protocol_Notification(reader, size); - else - return 0; // not known + switch(code) + { + case TLSEXT_SERVER_NAME_INDICATION: + return new Server_Name_Indicator(reader, size); + + case TLSEXT_MAX_FRAGMENT_LENGTH: + return new Maximum_Fragment_Length(reader, size); + + case TLSEXT_SRP_IDENTIFIER: + return new SRP_Identifier(reader, size); + + case TLSEXT_USABLE_ELLIPTIC_CURVES: + return new Supported_Elliptic_Curves(reader, size); + + case TLSEXT_SAFE_RENEGOTIATION: + return new Renegotation_Extension(reader, size); + + case TLSEXT_SIGNATURE_ALGORITHMS: + return new Signature_Algorithms(reader, size); + + case TLSEXT_NEXT_PROTOCOL: + return new Next_Protocol_Notification(reader, size); + + default: + return 0; // not known + } } } @@ -276,6 +288,122 @@ MemoryVector<byte> Next_Protocol_Notification::serialize() const return buf; } +namespace { + +std::string tls_curve_id_to_name(u16bit id) + { + switch(id) + { + case 15: + return "secp160k1"; + case 16: + return "secp160r1"; + case 17: + return "secp160r2"; + case 18: + return "secp192k1"; + case 19: + return "secp192r1"; + case 20: + return "secp224k1"; + case 21: + return "secp224r1"; + case 22: + return "secp256k1"; + case 23: + return "secp256r1"; + case 24: + return "secp384r1"; + case 25: + return "secp521r1"; + default: + return ""; // something we don't know or support + } + } + +u16bit tls_name_to_curve_id(const std::string& name) + { + if(name == "secp160k1") + return 15; + if(name == "secp160r1") + return 16; + if(name == "secp160r2") + return 17; + if(name == "secp192k1") + return 18; + if(name == "secp192r1") + return 19; + if(name == "secp224k1") + return 20; + if(name == "secp224r1") + return 21; + if(name == "secp256k1") + return 22; + if(name == "secp256r1") + return 23; + if(name == "secp384r1") + return 24; + if(name == "secp521r1") + return 25; + + throw Invalid_Argument("tls_name_to_curve_id unknown name " + name); + } + +} + +MemoryVector<byte> Supported_Elliptic_Curves::serialize() const + { + MemoryVector<byte> buf(2); + + for(size_t i = 0; i != m_curves.size(); ++i) + { + const u16bit id = tls_name_to_curve_id(m_curves[i]); + buf.push_back(get_byte(0, id)); + buf.push_back(get_byte(1, id)); + } + + buf[0] = get_byte<u16bit>(0, buf.size()-2); + buf[1] = get_byte<u16bit>(1, buf.size()-2); + } + +Supported_Elliptic_Curves::Supported_Elliptic_Curves() + { + m_curves.push_back("secp521r1"); + m_curves.push_back("secp384r1"); + m_curves.push_back("secp256r1"); + m_curves.push_back("secp256k1"); + m_curves.push_back("secp224r1"); + m_curves.push_back("secp224k1"); + m_curves.push_back("secp192r1"); + m_curves.push_back("secp192k1"); + m_curves.push_back("secp160r2"); + m_curves.push_back("secp160r1"); + m_curves.push_back("secp160k1"); + } + +Supported_Elliptic_Curves::Supported_Elliptic_Curves(TLS_Data_Reader& reader, + u16bit extension_size) + { + u16bit len = reader.get_u16bit(); + + if(len + 2 != extension_size) + throw Decoding_Error("Inconsistent length field in elliptic curve list"); + + if(len % 2 == 1) + throw Decoding_Error("Elliptic curve list of strange size"); + + len /= 2; + + for(size_t i = 0; i != len; ++i) + { + const u16bit id = reader.get_u16bit(); + const std::string name = tls_curve_id_to_name(id); + + if(name != "") + m_curves.push_back(name); + } + } + std::string Signature_Algorithms::hash_algo_name(byte code) { switch(code) diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 2b386d9f5..d0aee6d04 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -189,6 +189,31 @@ class Next_Protocol_Notification : public TLS_Extension }; /** +* Supported Elliptic Curves Extension (RFC 4492) +*/ +class Supported_Elliptic_Curves : public TLS_Extension + { + public: + static TLS_Handshake_Extension_Type static_type() + { return TLSEXT_USABLE_ELLIPTIC_CURVES; } + + TLS_Handshake_Extension_Type type() const { return static_type(); } + + const std::vector<std::string>& curves() const { return m_curves; } + + MemoryVector<byte> serialize() const; + + Supported_Elliptic_Curves(); // default values, for client + + Supported_Elliptic_Curves(TLS_Data_Reader& reader, + u16bit extension_size); + + bool empty() const { return m_curves.empty(); } + private: + std::vector<std::string> m_curves; + }; + +/** * Signature Algorithms Extension for TLS 1.2 (RFC 5246) */ class Signature_Algorithms : public TLS_Extension |