blob: 8fdae0869a64206d58666bd832178fc1172eb1da [file] [log] [blame]
#ifndef PROTON_SSL_H
#define PROTON_SSL_H 1
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include <proton/import_export.h>
#include <proton/type_compat.h>
#include <proton/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @file
* API for using SSL with the Transport Layer.
*
* A Transport may be configured to use SSL for encryption and/or authentication. A
* Transport can be configured as either an "SSL client" or an "SSL server". An SSL
* client is the party that proactively establishes a connection to an SSL server. An SSL
* server is the party that accepts a connection request from a remote SSL client.
*
* This SSL implementation defines the following objects:
* @li A top-level object that stores the configuration used by one or more SSL
* sessions (pn_ssl_domain_t).
* @li A per-connection SSL session object that performs the encryption/authentication
* associated with the transport (pn_ssl_t).
* @li The encryption parameters negotiated for the SSL session (pn_ssl_state_t).
*
* A pn_ssl_domain_t object must be created and configured before an SSL session can be
* established. The pn_ssl_domain_t is used to construct an SSL session (pn_ssl_t). The
* session "adopts" its configuration from the pn_ssl_domain_t that was used to create it.
* For example, pn_ssl_domain_t can be configured as either a "client" or a "server". SSL
* sessions constructed from this domain will perform the corresponding role (either
* client or server).
*
* If either an SSL server or client needs to identify itself with the remote node, it
* must have its SSL certificate configured (see ::pn_ssl_domain_set_credentials()).
*
* If either an SSL server or client needs to verify the identity of the remote node, it
* must have its database of trusted CAs configured (see ::pn_ssl_domain_set_trusted_ca_db()).
*
* An SSL server connection may allow the remote client to connect without SSL (eg. "in
* the clear"), see ::pn_ssl_domain_allow_unsecured_client().
*
* The level of verification required of the remote may be configured (see
* ::pn_ssl_domain_set_peer_authentication)
*
* Support for SSL Client Session resume is provided (see ::pn_ssl_init,
* ::pn_ssl_resume_status).
*
* @defgroup ssl SSL
* @ingroup transport
* @{
*/
typedef struct pn_ssl_domain_t pn_ssl_domain_t;
typedef struct pn_ssl_t pn_ssl_t;
/** Determines the type of SSL endpoint. */
typedef enum {
PN_SSL_MODE_CLIENT=1, /**< Local connection endpoint is an SSL client */
PN_SSL_MODE_SERVER /**< Local connection endpoint is an SSL server */
} pn_ssl_mode_t;
/** Indicates whether an SSL session has been resumed. */
typedef enum {
PN_SSL_RESUME_UNKNOWN, /**< Session resume state unknown/not supported */
PN_SSL_RESUME_NEW, /**< Session renegotiated - not resumed */
PN_SSL_RESUME_REUSED /**< Session resumed from previous session. */
} pn_ssl_resume_status_t;
/** Tests for SSL implementation present
*
* @return true if we support SSL, false if not
*/
PN_EXTERN bool pn_ssl_present( void );
/** Create an SSL configuration domain
*
* This method allocates an SSL domain object. This object is used to hold the SSL
* configuration for one or more SSL sessions. The SSL session object (pn_ssl_t) is
* allocated from this object.
*
* @param[in] mode the role, client or server, assumed by all SSL sessions created
* with this domain.
* @return a pointer to the SSL domain, if SSL support is present.
*/
PN_EXTERN pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode);
/** Release an SSL configuration domain
*
* This method frees an SSL domain object allocated by ::pn_ssl_domain.
* @param[in] domain the domain to destroy.
*/
PN_EXTERN void pn_ssl_domain_free( pn_ssl_domain_t *domain );
/** Set the certificate that identifies the local node to the remote.
*
* This certificate establishes the identity for the local node for all SSL sessions
* created from this domain. It will be sent to the remote if the remote needs to verify
* the identity of this node. This may be used for both SSL servers and SSL clients (if
* client authentication is required by the server).
*
* @note This setting effects only those pn_ssl_t objects created after this call
* returns. pn_ssl_t objects created before invoking this method will use the domain's
* previous setting.
*
* @param[in] domain the ssl domain that will use this certificate.
* @param[in] credential_1 specifier for the file/database containing the identifying
* certificate. For Openssl users, this is a PEM file. For Windows SChannel users, this is
* the PKCS#12 file or system store.
* @param[in] credential_2 an optional key to access the identifying certificate. For
* Openssl users, this is an optional PEM file containing the private key used to sign the
* certificate. For Windows SChannel users, this is the friendly name of the
* self-identifying certificate if there are multiple certificates in the store.
* @param[in] password the password used to sign the key, else NULL if key is not
* protected.
* @return 0 on success
*/
PN_EXTERN int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
const char *credential_1,
const char *credential_2,
const char *password);
/** Configure the set of trusted CA certificates used by this domain to verify peers.
*
* If the local SSL client/server needs to verify the identity of the remote, it must
* validate the signature of the remote's certificate. This function sets the database of
* trusted CAs that will be used to verify the signature of the remote's certificate.
*
* @note This setting effects only those pn_ssl_t objects created after this call
* returns. pn_ssl_t objects created before invoking this method will use the domain's
* previous setting.
*
* @param[in] domain the ssl domain that will use the database.
* @param[in] certificate_db database of trusted CAs, used to authenticate the peer.
* @return 0 on success
*/
PN_EXTERN int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain,
const char *certificate_db);
/** Determines the level of peer validation.
*
* ANONYMOUS_PEER does not require a valid certificate, and permits use of ciphers that
* do not provide authentication.
*
* VERIFY_PEER will only connect to those peers that provide a valid identifying
* certificate signed by a trusted CA and are using an authenticated cipher.
*
* VERIFY_PEER_NAME is like VERIFY_PEER, but also requires the peer's identity as
* contained in the certificate to be valid (see ::pn_ssl_set_peer_hostname).
*
* ANONYMOUS_PEER is configured by default.
*/
typedef enum {
PN_SSL_VERIFY_NULL=0, /**< internal use only */
PN_SSL_VERIFY_PEER, /**< require peer to provide a valid identifying certificate */
PN_SSL_ANONYMOUS_PEER, /**< do not require a certificate nor cipher authorization */
PN_SSL_VERIFY_PEER_NAME /**< require valid certificate and matching name */
} pn_ssl_verify_mode_t;
/** Configure the level of verification used on the peer certificate.
*
* This method controls how the peer's certificate is validated, if at all. By default,
* neither servers nor clients attempt to verify their peers (PN_SSL_ANONYMOUS_PEER).
* Once certificates and trusted CAs are configured, peer verification can be enabled.
*
* @note In order to verify a peer, a trusted CA must be configured. See
* ::pn_ssl_domain_set_trusted_ca_db().
*
* @note Servers must provide their own certificate when verifying a peer. See
* ::pn_ssl_domain_set_credentials().
*
* @note This setting effects only those pn_ssl_t objects created after this call
* returns. pn_ssl_t objects created before invoking this method will use the domain's
* previous setting.
*
* @param[in] domain the ssl domain to configure.
* @param[in] mode the level of validation to apply to the peer
* @param[in] trusted_CAs path to a database of trusted CAs that the server will advertise
* to the peer client if the server has been configured to verify its peer.
* @return 0 on success
*/
PN_EXTERN int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
const pn_ssl_verify_mode_t mode,
const char *trusted_CAs);
/** Permit a server to accept connection requests from non-SSL clients.
*
* This configures the server to "sniff" the incoming client data stream, and dynamically
* determine whether SSL/TLS is being used. This option is disabled by default: only
* clients using SSL/TLS are accepted.
*
* @param[in] domain the domain (server) that will accept the client connections.
* @return 0 on success
*/
PN_EXTERN int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain);
/** Create a new SSL session object associated with a transport.
*
* A transport must have an SSL object in order to "speak" SSL over its connection. This
* method allocates an SSL object associates it with the transport.
*
* @param[in] transport the transport that will own the new SSL session.
* @return a pointer to the SSL object configured for this transport. Returns NULL if
* no SSL session is associated with the transport.
*/
PN_EXTERN pn_ssl_t *pn_ssl(pn_transport_t *transport);
/** Initialize an SSL session.
*
* This method configures an SSL object using the configuration provided by the given
* domain.
*
* @param[in] ssl the ssl session to configured.
* @param[in] domain the ssl domain used to configure the SSL session.
* @param[in] session_id if supplied, attempt to resume a previous SSL
* session that used the same session_id. If no previous SSL session
* is available, a new session will be created using the session_id
* and stored for future session restore (see ::::pn_ssl_resume_status).
* @return 0 on success, else an error code.
*/
PN_EXTERN int pn_ssl_init( pn_ssl_t *ssl,
pn_ssl_domain_t *domain,
const char *session_id);
/** Get the name of the Cipher that is currently in use.
*
* Gets a text description of the cipher that is currently active, or returns FALSE if SSL
* is not active (no cipher). Note that the cipher in use may change over time due to
* renegotiation or other changes to the SSL state.
*
* @param[in] ssl the ssl client/server to query.
* @param[in,out] buffer buffer of size bytes to hold cipher name
* @param[in] size maximum number of bytes in buffer.
* @return True if cipher name written to buffer, False if no cipher in use.
*/
PN_EXTERN bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *buffer, size_t size);
/** Get the SSF (security strength factor) of the Cipher that is currently in use.
*
* @param[in] ssl the ssl client/server to query.
* @return the ssf, note that 0 means no security.
*/
PN_EXTERN int pn_ssl_get_ssf(pn_ssl_t *ssl);
/** Get the name of the SSL protocol that is currently in use.
*
* Gets a text description of the SSL protocol that is currently active, or returns FALSE if SSL
* is not active. Note that the protocol may change over time due to renegotiation.
*
* @param[in] ssl the ssl client/server to query.
* @param[in,out] buffer buffer of size bytes to hold the version identifier
* @param[in] size maximum number of bytes in buffer.
* @return True if the version information was written to buffer, False if SSL connection
* not ready.
*/
PN_EXTERN bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size);
/** Check whether the state has been resumed.
*
* Used for client session resume. When called on an active session, indicates whether
* the state has been resumed from a previous session.
*
* @note This is a best-effort service - there is no guarantee that the remote server will
* accept the resumed parameters. The remote server may choose to ignore these
* parameters, and request a re-negotiation instead.
*
* @param[in] ssl the ssl session to check
* @return status code indicating whether or not the session has been resumed.
*/
PN_EXTERN pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl );
/** Set the expected identity of the remote peer.
*
* By default, SSL will use the hostname associated with the connection that
* the transport is bound to (see ::pn_connection_set_hostname). This method
* allows the caller to override that default.
*
* The hostname is used for two purposes: 1) when set on an SSL client, it is sent to the
* server during the handshake (if Server Name Indication is supported), and 2) it is used
* to check against the identifying name provided in the peer's certificate. If the
* supplied name does not exactly match a SubjectAltName (type DNS name), or the
* CommonName entry in the peer's certificate, the peer is considered unauthenticated
* (potential imposter), and the SSL connection is aborted.
*
* @note Verification of the hostname is only done if PN_SSL_VERIFY_PEER_NAME is enabled.
* See ::pn_ssl_domain_set_peer_authentication.
*
* @param[in] ssl the ssl session.
* @param[in] hostname the expected identity of the remote. Must conform to the syntax as
* given in RFC1034, Section 3.5.
* @return 0 on success.
*/
PN_EXTERN int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname);
/** Access the configured peer identity.
*
* Return the expected identity of the remote peer, as set by ::pn_ssl_set_peer_hostname.
*
* @param[in] ssl the ssl session.
* @param[out] hostname buffer to hold the null-terminated name string. If null, no string
* is written.
* @param[in,out] bufsize on input set to the number of octets in hostname. On output, set
* to the number of octets needed to hold the value of hostname plus a null byte. Zero if
* no hostname set.
* @return 0 on success.
*/
PN_EXTERN int pn_ssl_get_peer_hostname( pn_ssl_t *ssl, char *hostname, size_t *bufsize );
/** Get the subject from the peers certificate.
*
* @param[in] ssl the ssl client/server to query.
* @return A null terminated string representing the full subject,
* which is valid until the ssl object is destroyed.
*/
PN_EXTERN const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl);
/**
* Enumeration identifying the sub fields of the subject field in the ssl certificate.
*/
typedef enum {
PN_SSL_CERT_SUBJECT_COUNTRY_NAME,
PN_SSL_CERT_SUBJECT_STATE_OR_PROVINCE,
PN_SSL_CERT_SUBJECT_CITY_OR_LOCALITY,
PN_SSL_CERT_SUBJECT_ORGANIZATION_NAME,
PN_SSL_CERT_SUBJECT_ORGANIZATION_UNIT,
PN_SSL_CERT_SUBJECT_COMMON_NAME
} pn_ssl_cert_subject_subfield;
/**
* Enumeration identifying hashing algorithm.
*/
typedef enum {
PN_SSL_SHA1, /* Produces hash that is 20 bytes long */
PN_SSL_SHA256, /* Produces hash that is 32 bytes long */
PN_SSL_SHA512, /* Produces hash that is 64 bytes long */
PN_SSL_MD5 /* Produces hash that is 16 bytes long */
} pn_ssl_hash_alg;
/**
* Get the fingerprint of the certificate. The certificate fingerprint (as displayed in the Fingerprints section when
* looking at a certificate with say the Firefox browser) is the hexadecimal hash of the entire certificate.
* The fingerprint is not part of the certificate, rather it is computed from the certificate and can be used to uniquely identify a certificate.
* @param[in] ssl0 the ssl client/server to query
* @param[in] fingerprint char pointer. The certificate fingerprint (in hex format) will be populated in this array.
* If sha1 is the digest name, the fingerprint is 41 characters long (40 + 1 '\0' character), 65 characters long for
* sha256 and 129 characters long for sha512 and 33 characters for md5.
* @param[in] fingerprint_length - Must be at >= 33 for md5, >= 41 for sha1, >= 65 for sha256 and >=129 for sha512.
* @param[in] hash_alg the hash algorithm to use. Must be of type pn_ssl_hash_alg (currently supports sha1, sha256, sha512 and md5)
* @return error code - Returns 0 on success. Return a value less than zero if there were any errors. Upon execution of this function,
* char *fingerprint will contain the appropriate null terminated hex fingerprint
*/
PN_EXTERN int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl0,
char *fingerprint,
size_t fingerprint_length,
pn_ssl_hash_alg hash_alg);
/**
* Returns a char pointer that contains the value of the sub field of the subject field in the ssl certificate. The subject field usually contains the following sub fields -
* C = ISO3166 two character country code
* ST = state or province
* L = Locality; generally means city
* O = Organization - Company Name
* OU = Organization Unit - division or unit
* CN = CommonName
* @param[in] ssl0 the ssl client/server to query
* @param[in] field The enumeration pn_ssl_cert_subject_subfield representing the required sub field.
* @return A null terminated string which contains the requested sub field value which is valid until the ssl object is destroyed.
*/
PN_EXTERN const char* pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subject_subfield field);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ssl.h */