#ifndef _NPT_TLS_H_
#define _NPT_TLS_H_
#include "NptConfig.h"
#include "NptStreams.h"
#include "NptTime.h"
#include "NptHttp.h"
const NPT_Result NPT_ERROR_INVALID_PASSWORD = (NPT_ERROR_BASE_TLS-1);
const NPT_Result NPT_ERROR_TLS_INVALID_HANDSHAKE = (NPT_ERROR_BASE_TLS-2);
const NPT_Result NPT_ERROR_TLS_INVALID_PROTOCOL_MESSAGE = (NPT_ERROR_BASE_TLS-3);
const NPT_Result NPT_ERROR_TLS_INVALID_HMAC = (NPT_ERROR_BASE_TLS-4);
const NPT_Result NPT_ERROR_TLS_INVALID_VERSION = (NPT_ERROR_BASE_TLS-5);
const NPT_Result NPT_ERROR_TLS_INVALID_SESSION = (NPT_ERROR_BASE_TLS-6);
const NPT_Result NPT_ERROR_TLS_NO_CIPHER = (NPT_ERROR_BASE_TLS-7);
const NPT_Result NPT_ERROR_TLS_BAD_CERTIFICATE = (NPT_ERROR_BASE_TLS-8);
const NPT_Result NPT_ERROR_TLS_INVALID_KEY = (NPT_ERROR_BASE_TLS-9);
const NPT_Result NPT_ERROR_TLS_NO_CLIENT_RENEGOTIATION = (NPT_ERROR_BASE_TLS-10);
const NPT_Result NPT_ERROR_TLS_INVALID_FINISHED_MESSAGE = (NPT_ERROR_BASE_TLS-11);
const NPT_Result NPT_ERROR_TLS_NO_CERTIFICATE_DEFINED = (NPT_ERROR_BASE_TLS-12);
const NPT_Result NPT_ERROR_TLS_ALERT_HANDSHAKE_FAILED = (NPT_ERROR_BASE_TLS-13);
const NPT_Result NPT_ERROR_TLS_ALERT_BAD_CERTIFICATE = (NPT_ERROR_BASE_TLS-14);
const NPT_Result NPT_ERROR_TLS_ALERT_INVALID_VERSION = (NPT_ERROR_BASE_TLS-15);
const NPT_Result NPT_ERROR_TLS_ALERT_BAD_RECORD_MAC = (NPT_ERROR_BASE_TLS-16);
const NPT_Result NPT_ERROR_TLS_ALERT_DECODE_ERROR = (NPT_ERROR_BASE_TLS-17);
const NPT_Result NPT_ERROR_TLS_ALERT_DECRYPT_ERROR = (NPT_ERROR_BASE_TLS-18);
const NPT_Result NPT_ERROR_TLS_ALERT_ILLEGAL_PARAMETER = (NPT_ERROR_BASE_TLS-19);
const NPT_Result NPT_ERROR_TLS_ALERT_UNEXPECTED_MESSAGE = (NPT_ERROR_BASE_TLS-20);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_FAILURE = (NPT_ERROR_BASE_TLS-21);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_NO_TRUST_ANCHOR = (NPT_ERROR_BASE_TLS-22);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_BAD_SIGNATURE = (NPT_ERROR_BASE_TLS-23);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_NOT_YET_VALID = (NPT_ERROR_BASE_TLS-24);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_EXPIRED = (NPT_ERROR_BASE_TLS-25);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_SELF_SIGNED = (NPT_ERROR_BASE_TLS-26);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_INVALID_CHAIN = (NPT_ERROR_BASE_TLS-27);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_UNSUPPORTED_DIGEST = (NPT_ERROR_BASE_TLS-28);
const NPT_Result NPT_ERROR_TLS_CERTIFICATE_INVALID_PRIVATE_KEY = (NPT_ERROR_BASE_TLS-29);
const NPT_Result NPT_ERROR_TLS_DNS_NAME_MISMATCH = (NPT_ERROR_BASE_TLS-30);
const unsigned int NPT_TLS_NULL_WITH_NULL_NULL = 0x00;
const unsigned int NPT_TLS_RSA_WITH_RC4_128_MD5 = 0x04;
const unsigned int NPT_TLS_RSA_WITH_RC4_128_SHA = 0x05;
const unsigned int NPT_TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F;
const unsigned int NPT_TLS_RSA_WITH_AES_256_CBC_SHA = 0x35;
class NPT_TlsContextImpl;
class NPT_TlsSessionImpl;
typedef enum {
NPT_TLS_KEY_FORMAT_RSA_PRIVATE,
NPT_TLS_KEY_FORMAT_PKCS8,
NPT_TLS_KEY_FORMAT_PKCS12
} NPT_TlsKeyFormat;
struct NPT_TlsTrustAnchorData {
const unsigned char* cert_data;
unsigned int cert_size;
};
class NPT_Tls
{
public:
static const NPT_TlsTrustAnchorData* GetDefaultTrustAnchors(NPT_Ordinal indx=0);
static bool MatchDnsNames(const char* hostname,
const NPT_List<NPT_String>& dns_names);
static bool MatchDnsName(const char* hostname, const char* dns_name);
private:
NPT_Tls() {};
};
class NPT_TlsContext : public NPT_AutomaticCleaner::Singleton
{
public:
enum {
OPTION_VERIFY_LATER = 1,
OPTION_REQUIRE_CLIENT_CERTIFICATE = 2,
OPTION_ADD_DEFAULT_TRUST_ANCHORS = 4,
OPTION_NO_SESSION_CACHE = 8
};
NPT_TlsContext(NPT_Flags options=0);
~NPT_TlsContext();
NPT_Result LoadKey(NPT_TlsKeyFormat key_format,
const unsigned char* key_data,
NPT_Size key_data_size,
const char* password);
NPT_Result SelfSignCertificate(const char* common_name,
const char* organization,
const char* organizational_name);
NPT_Result AddTrustAnchor(const unsigned char* ta_data,
NPT_Size ta_data_size);
NPT_Result AddTrustAnchors(const NPT_TlsTrustAnchorData* anchors,
NPT_Cardinal anchor_count = 0);
protected:
NPT_TlsContextImpl* m_Impl;
friend class NPT_TlsSession;
friend class NPT_TlsClientSession;
friend class NPT_TlsServerSession;
};
struct NPT_TlsCertificateInfo
{
struct _subject {
NPT_String common_name;
NPT_String organization;
NPT_String organizational_name;
} subject;
struct _issuer {
NPT_String common_name;
NPT_String organization;
NPT_String organizational_name;
} issuer;
struct _fingerprint {
unsigned char sha1[20];
unsigned char md5[16];
} fingerprint;
NPT_DateTime issue_date;
NPT_DateTime expiration_date;
NPT_List<NPT_String> alternate_names;
};
class NPT_TlsSession
{
public:
virtual ~NPT_TlsSession();
virtual NPT_Result Handshake();
virtual NPT_Result GetHandshakeStatus();
virtual NPT_Result GetPeerCertificateInfo(NPT_TlsCertificateInfo& info, NPT_Ordinal position=0);
virtual NPT_Result VerifyPeerCertificate();
virtual NPT_Result VerifyDnsNameMatch(const char* hostname);
virtual NPT_Result GetSessionId(NPT_DataBuffer& session_id);
virtual NPT_UInt32 GetCipherSuiteId();
virtual NPT_Result GetInputStream(NPT_InputStreamReference& stream);
virtual NPT_Result GetOutputStream(NPT_OutputStreamReference& stream);
protected:
NPT_TlsSession(NPT_TlsContext& context,
NPT_TlsSessionImpl* impl);
NPT_TlsContext& m_Context;
NPT_Reference<NPT_TlsSessionImpl> m_Impl;
NPT_InputStreamReference m_InputStream;
NPT_OutputStreamReference m_OutputStream;
};
class NPT_TlsClientSession : public NPT_TlsSession
{
public:
NPT_TlsClientSession(NPT_TlsContext& context,
NPT_InputStreamReference& input,
NPT_OutputStreamReference& output);
};
class NPT_TlsServerSession : public NPT_TlsSession
{
public:
NPT_TlsServerSession(NPT_TlsContext& context,
NPT_InputStreamReference& input,
NPT_OutputStreamReference& output);
};
#if defined(NPT_CONFIG_ENABLE_TLS)
class NPT_HttpTlsConnector : public NPT_HttpClient::Connector
{
public:
enum {
OPTION_ACCEPT_SELF_SIGNED_CERTS = 1,
OPTION_ACCEPT_HOSTNAME_MISMATCH = 2
};
NPT_HttpTlsConnector(NPT_Flags options = 0);
NPT_HttpTlsConnector(NPT_TlsContext& tls_context, NPT_Flags options = 0);
virtual ~NPT_HttpTlsConnector() {}
NPT_TlsContext& GetTlsContext() { return m_TlsContext; }
virtual NPT_Result VerifyPeer(NPT_TlsClientSession& session,
const char* hostname);
virtual NPT_Result Connect(const NPT_HttpUrl& url,
NPT_HttpClient& client,
const NPT_HttpProxyAddress* proxy,
bool reuse,
NPT_HttpClient::Connection*& connection);
private:
static NPT_TlsContext& GetDefaultTlsContext();
static NPT_TlsContext* DefaultTlsContext;
NPT_TlsContext& m_TlsContext;
NPT_Flags m_Options;
};
#else
class NPT_HttpTlsConnector : public NPT_HttpClient::Connector
{
public:
virtual ~NPT_HttpTlsConnector() {}
virtual NPT_Result Connect(const NPT_HttpUrl& url,
NPT_HttpClient& client,
const NPT_HttpProxyAddress* proxy,
bool reuse,
NPT_HttpClient::Connection*& connection);
};
#endif
#if defined(NPT_CONFIG_ENABLE_TLS)
#include "NptTlsDefaultTrustAnchorsBase.h"
#include "NptTlsDefaultTrustAnchorsExtended.h"
#endif
#endif