| #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 |
| * |
| * @copybrief ssl |
| * |
| * @addtogroup ssl |
| * @{ |
| */ |
| |
| /** |
| * 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). |
| * |
| * 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 an SSL session is created without a pn_ssl_domain_t object then a default will be used |
| * (see ::pn_ssl_init()). |
| * |
| * 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. By default this will be set up to use |
| * the default system database of trusted CA. But this can be changed |
| * (see ::pn_ssl_domain_set_trusted_ca_db()). |
| * |
| * 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). |
| */ |
| typedef struct pn_ssl_domain_t pn_ssl_domain_t; |
| |
| /** |
| * @see pn_ssl |
| */ |
| 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. |
| * |
| * @note By default the list of trusted CA certificates will be set to the system default. |
| * What this is is depends on the OS and the SSL implementation used: For OpenSSL the default |
| * will depend on how the OS is set up. When using the Windows SChannel implementation the default |
| * will be the users default trusted certificate store. |
| * |
| * @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); |
| |
| /** |
| * Configure the list of permitted TLS protocols |
| * |
| * @param[in] domain the ssl domain to configure. |
| * @param[in] protocols string representing the protocol list. |
| * This list is a space separated string of the allowed TLS protocols, |
| * The current possibilities are TLSv1 TLSv1.1 TLSv1.2 TLSv1.3. None of the earlier SSL |
| * protocols are allowed for security reason. |
| * |
| * @note If this API not called then all the TLS protocols are allowed. The API only acts to |
| * restrict the allowed protocols to the specified set. |
| * @return 0 on success |
| */ |
| PN_EXTERN int pn_ssl_domain_set_protocols(pn_ssl_domain_t *domain, const char *protocols); |
| |
| /** |
| * Configure the list of permitted ciphers |
| * |
| * @note The syntax of the permitted list is undefined and will depend on the |
| * underlying SSL implementation. |
| * |
| * @param[in] domain the ssl domain to configure. |
| * @param[in] ciphers string representing the cipher list |
| * @return 0 on success |
| */ |
| PN_EXTERN int pn_ssl_domain_set_ciphers(pn_ssl_domain_t *domain, const char *ciphers); |
| |
| /** |
| * **Deprecated** - Use ::pn_transport_require_encrytion() |
| * |
| * 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 with defaults or the configuration provided by the given |
| * domain. |
| * |
| * @note The default client domain is a secure default generally usable. This uses the system default |
| * certificates and requires peer name verification. |
| * |
| * @note However the default server domain is only really useful for test servers. This is because for |
| * a useful server you *need* to set up certificates to identify it so that clients can connect without |
| * being subject to "man-in-the-middle" attacks - see ::pn_ssl_domain_set_credentials() for details. |
| * |
| * @param[in] ssl the ssl session to configured. |
| * @param[in] domain the ssl domain used to configure the SSL session. If this value is NULL |
| * then use a default domain. This will be a client domain if the ssl object is part of a client transport |
| * and a server domain if the ssl object is part of a server transport. |
| * the transport the pn_ssl_t object |
| * @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 */ |