00001 #ifndef PROTON_SSL_H 00002 #define PROTON_SSL_H 1 00003 00004 /* 00005 * 00006 * Licensed to the Apache Software Foundation (ASF) under one 00007 * or more contributor license agreements. See the NOTICE file 00008 * distributed with this work for additional information 00009 * regarding copyright ownership. The ASF licenses this file 00010 * to you under the Apache License, Version 2.0 (the 00011 * "License"); you may not use this file except in compliance 00012 * with the License. You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, 00017 * software distributed under the License is distributed on an 00018 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 00019 * KIND, either express or implied. See the License for the 00020 * specific language governing permissions and limitations 00021 * under the License. 00022 * 00023 */ 00024 00025 #include <proton/import_export.h> 00026 #include <proton/type_compat.h> 00027 #include <proton/types.h> 00028 00029 #ifdef __cplusplus 00030 extern "C" { 00031 #endif 00032 00033 /** @file 00034 * API for using SSL with the Transport Layer. 00035 * 00036 * A Transport may be configured to use SSL for encryption and/or authentication. A 00037 * Transport can be configured as either an "SSL client" or an "SSL server". An SSL 00038 * client is the party that proactively establishes a connection to an SSL server. An SSL 00039 * server is the party that accepts a connection request from a remote SSL client. 00040 * 00041 * This SSL implementation defines the following objects: 00042 00043 * @li A top-level object that stores the configuration used by one or more SSL 00044 * sessions (pn_ssl_domain_t). 00045 * @li A per-connection SSL session object that performs the encryption/authentication 00046 * associated with the transport (pn_ssl_t). 00047 * @li The encryption parameters negotiated for the SSL session (pn_ssl_state_t). 00048 * 00049 * A pn_ssl_domain_t object must be created and configured before an SSL session can be 00050 * established. The pn_ssl_domain_t is used to construct an SSL session (pn_ssl_t). The 00051 * session "adopts" its configuration from the pn_ssl_domain_t that was used to create it. 00052 * For example, pn_ssl_domain_t can be configured as either a "client" or a "server". SSL 00053 * sessions constructed from this domain will perform the corresponding role (either 00054 * client or server). 00055 * 00056 * If either an SSL server or client needs to identify itself with the remote node, it 00057 * must have its SSL certificate configured (see ::pn_ssl_domain_set_credentials()). 00058 * 00059 * If either an SSL server or client needs to verify the identity of the remote node, it 00060 * must have its database of trusted CAs configured (see ::pn_ssl_domain_set_trusted_ca_db()). 00061 * 00062 * An SSL server connection may allow the remote client to connect without SSL (eg. "in 00063 * the clear"), see ::pn_ssl_domain_allow_unsecured_client(). 00064 * 00065 * The level of verification required of the remote may be configured (see 00066 * ::pn_ssl_domain_set_peer_authentication) 00067 * 00068 * Support for SSL Client Session resume is provided (see ::pn_ssl_init, 00069 * ::pn_ssl_resume_status). 00070 * 00071 * @defgroup ssl SSL 00072 * @ingroup transport 00073 * @{ 00074 */ 00075 00076 typedef struct pn_ssl_domain_t pn_ssl_domain_t; 00077 typedef struct pn_ssl_t pn_ssl_t; 00078 00079 /** Determines the type of SSL endpoint. */ 00080 typedef enum { 00081 PN_SSL_MODE_CLIENT=1, /**< Local connection endpoint is an SSL client */ 00082 PN_SSL_MODE_SERVER /**< Local connection endpoint is an SSL server */ 00083 } pn_ssl_mode_t; 00084 00085 /** Indicates whether an SSL session has been resumed. */ 00086 typedef enum { 00087 PN_SSL_RESUME_UNKNOWN, /**< Session resume state unknown/not supported */ 00088 PN_SSL_RESUME_NEW, /**< Session renegotiated - not resumed */ 00089 PN_SSL_RESUME_REUSED /**< Session resumed from previous session. */ 00090 } pn_ssl_resume_status_t; 00091 00092 /** Tests for SSL implementation present 00093 * 00094 * @return true if we support SSL, false if not 00095 */ 00096 PN_EXTERN bool pn_ssl_present( void ); 00097 00098 /** Create an SSL configuration domain 00099 * 00100 * This method allocates an SSL domain object. This object is used to hold the SSL 00101 * configuration for one or more SSL sessions. The SSL session object (pn_ssl_t) is 00102 * allocated from this object. 00103 * 00104 * @param[in] mode the role, client or server, assumed by all SSL sessions created 00105 * with this domain. 00106 * @return a pointer to the SSL domain, if SSL support is present. 00107 */ 00108 PN_EXTERN pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode); 00109 00110 /** Release an SSL configuration domain 00111 * 00112 * This method frees an SSL domain object allocated by ::pn_ssl_domain. 00113 * @param[in] domain the domain to destroy. 00114 */ 00115 PN_EXTERN void pn_ssl_domain_free( pn_ssl_domain_t *domain ); 00116 00117 /** Set the certificate that identifies the local node to the remote. 00118 * 00119 * This certificate establishes the identity for the local node for all SSL sessions 00120 * created from this domain. It will be sent to the remote if the remote needs to verify 00121 * the identity of this node. This may be used for both SSL servers and SSL clients (if 00122 * client authentication is required by the server). 00123 * 00124 * @note This setting effects only those pn_ssl_t objects created after this call 00125 * returns. pn_ssl_t objects created before invoking this method will use the domain's 00126 * previous setting. 00127 * 00128 * @param[in] domain the ssl domain that will use this certificate. 00129 * @param[in] credential_1 specifier for the file/database containing the identifying 00130 * certificate. For Openssl users, this is a PEM file. For Windows SChannel users, this is 00131 * the PKCS#12 file or system store. 00132 * @param[in] credential_2 an optional key to access the identifying certificate. For 00133 * Openssl users, this is an optional PEM file containing the private key used to sign the 00134 * certificate. For Windows SChannel users, this is the friendly name of the 00135 * self-identifying certificate if there are multiple certificates in the store. 00136 * @param[in] password the password used to sign the key, else NULL if key is not 00137 * protected. 00138 * @return 0 on success 00139 */ 00140 PN_EXTERN int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain, 00141 const char *credential_1, 00142 const char *credential_2, 00143 const char *password); 00144 00145 /** Configure the set of trusted CA certificates used by this domain to verify peers. 00146 * 00147 * If the local SSL client/server needs to verify the identity of the remote, it must 00148 * validate the signature of the remote's certificate. This function sets the database of 00149 * trusted CAs that will be used to verify the signature of the remote's certificate. 00150 * 00151 * @note This setting effects only those pn_ssl_t objects created after this call 00152 * returns. pn_ssl_t objects created before invoking this method will use the domain's 00153 * previous setting. 00154 * 00155 * @param[in] domain the ssl domain that will use the database. 00156 * @param[in] certificate_db database of trusted CAs, used to authenticate the peer. 00157 * @return 0 on success 00158 */ 00159 PN_EXTERN int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain, 00160 const char *certificate_db); 00161 00162 /** Determines the level of peer validation. 00163 * 00164 * ANONYMOUS_PEER does not require a valid certificate, and permits use of ciphers that 00165 * do not provide authentication. 00166 * 00167 * VERIFY_PEER will only connect to those peers that provide a valid identifying 00168 * certificate signed by a trusted CA and are using an authenticated cipher. 00169 * 00170 * VERIFY_PEER_NAME is like VERIFY_PEER, but also requires the peer's identity as 00171 * contained in the certificate to be valid (see ::pn_ssl_set_peer_hostname). 00172 * 00173 * ANONYMOUS_PEER is configured by default. 00174 */ 00175 typedef enum { 00176 PN_SSL_VERIFY_NULL=0, /**< internal use only */ 00177 PN_SSL_VERIFY_PEER, /**< require peer to provide a valid identifying certificate */ 00178 PN_SSL_ANONYMOUS_PEER, /**< do not require a certificate nor cipher authorization */ 00179 PN_SSL_VERIFY_PEER_NAME /**< require valid certificate and matching name */ 00180 } pn_ssl_verify_mode_t; 00181 00182 /** Configure the level of verification used on the peer certificate. 00183 * 00184 * This method controls how the peer's certificate is validated, if at all. By default, 00185 * neither servers nor clients attempt to verify their peers (PN_SSL_ANONYMOUS_PEER). 00186 * Once certificates and trusted CAs are configured, peer verification can be enabled. 00187 * 00188 * @note In order to verify a peer, a trusted CA must be configured. See 00189 * ::pn_ssl_domain_set_trusted_ca_db(). 00190 * 00191 * @note Servers must provide their own certificate when verifying a peer. See 00192 * ::pn_ssl_domain_set_credentials(). 00193 * 00194 * @note This setting effects only those pn_ssl_t objects created after this call 00195 * returns. pn_ssl_t objects created before invoking this method will use the domain's 00196 * previous setting. 00197 * 00198 * @param[in] domain the ssl domain to configure. 00199 * @param[in] mode the level of validation to apply to the peer 00200 * @param[in] trusted_CAs path to a database of trusted CAs that the server will advertise 00201 * to the peer client if the server has been configured to verify its peer. 00202 * @return 0 on success 00203 */ 00204 PN_EXTERN int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain, 00205 const pn_ssl_verify_mode_t mode, 00206 const char *trusted_CAs); 00207 00208 /** Permit a server to accept connection requests from non-SSL clients. 00209 * 00210 * This configures the server to "sniff" the incoming client data stream, and dynamically 00211 * determine whether SSL/TLS is being used. This option is disabled by default: only 00212 * clients using SSL/TLS are accepted. 00213 * 00214 * @param[in] domain the domain (server) that will accept the client connections. 00215 * @return 0 on success 00216 */ 00217 PN_EXTERN int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain); 00218 00219 /** Create a new SSL session object associated with a transport. 00220 * 00221 * A transport must have an SSL object in order to "speak" SSL over its connection. This 00222 * method allocates an SSL object associates it with the transport. 00223 * 00224 * @param[in] transport the transport that will own the new SSL session. 00225 * @return a pointer to the SSL object configured for this transport. Returns NULL if 00226 * no SSL session is associated with the transport. 00227 */ 00228 PN_EXTERN pn_ssl_t *pn_ssl(pn_transport_t *transport); 00229 00230 /** Initialize an SSL session. 00231 * 00232 * This method configures an SSL object using the configuration provided by the given 00233 * domain. 00234 * 00235 * @param[in] ssl the ssl session to configured. 00236 * @param[in] domain the ssl domain used to configure the SSL session. 00237 * @param[in] session_id if supplied, attempt to resume a previous SSL 00238 * session that used the same session_id. If no previous SSL session 00239 * is available, a new session will be created using the session_id 00240 * and stored for future session restore (see ::::pn_ssl_resume_status). 00241 * @return 0 on success, else an error code. 00242 */ 00243 PN_EXTERN int pn_ssl_init( pn_ssl_t *ssl, 00244 pn_ssl_domain_t *domain, 00245 const char *session_id); 00246 00247 /** Get the name of the Cipher that is currently in use. 00248 * 00249 * Gets a text description of the cipher that is currently active, or returns FALSE if SSL 00250 * is not active (no cipher). Note that the cipher in use may change over time due to 00251 * renegotiation or other changes to the SSL state. 00252 * 00253 * @param[in] ssl the ssl client/server to query. 00254 * @param[in,out] buffer buffer of size bytes to hold cipher name 00255 * @param[in] size maximum number of bytes in buffer. 00256 * @return True if cipher name written to buffer, False if no cipher in use. 00257 */ 00258 PN_EXTERN bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *buffer, size_t size); 00259 00260 /** Get the SSF (security strength factor) of the Cipher that is currently in use. 00261 * 00262 * @param[in] ssl the ssl client/server to query. 00263 * @return the ssf, note that 0 means no security. 00264 */ 00265 PN_EXTERN int pn_ssl_get_ssf(pn_ssl_t *ssl); 00266 00267 /** Get the name of the SSL protocol that is currently in use. 00268 * 00269 * Gets a text description of the SSL protocol that is currently active, or returns FALSE if SSL 00270 * is not active. Note that the protocol may change over time due to renegotiation. 00271 * 00272 * @param[in] ssl the ssl client/server to query. 00273 * @param[in,out] buffer buffer of size bytes to hold the version identifier 00274 * @param[in] size maximum number of bytes in buffer. 00275 * @return True if the version information was written to buffer, False if SSL connection 00276 * not ready. 00277 */ 00278 PN_EXTERN bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size); 00279 00280 /** Check whether the state has been resumed. 00281 * 00282 * Used for client session resume. When called on an active session, indicates whether 00283 * the state has been resumed from a previous session. 00284 * 00285 * @note This is a best-effort service - there is no guarantee that the remote server will 00286 * accept the resumed parameters. The remote server may choose to ignore these 00287 * parameters, and request a re-negotiation instead. 00288 * 00289 * @param[in] ssl the ssl session to check 00290 * @return status code indicating whether or not the session has been resumed. 00291 */ 00292 PN_EXTERN pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl ); 00293 00294 /** Set the expected identity of the remote peer. 00295 * 00296 * By default, SSL will use the hostname associated with the connection that 00297 * the transport is bound to (see ::pn_connection_set_hostname). This method 00298 * allows the caller to override that default. 00299 * 00300 * The hostname is used for two purposes: 1) when set on an SSL client, it is sent to the 00301 * server during the handshake (if Server Name Indication is supported), and 2) it is used 00302 * to check against the identifying name provided in the peer's certificate. If the 00303 * supplied name does not exactly match a SubjectAltName (type DNS name), or the 00304 * CommonName entry in the peer's certificate, the peer is considered unauthenticated 00305 * (potential imposter), and the SSL connection is aborted. 00306 * 00307 * @note Verification of the hostname is only done if PN_SSL_VERIFY_PEER_NAME is enabled. 00308 * See ::pn_ssl_domain_set_peer_authentication. 00309 * 00310 * @param[in] ssl the ssl session. 00311 * @param[in] hostname the expected identity of the remote. Must conform to the syntax as 00312 * given in RFC1034, Section 3.5. 00313 * @return 0 on success. 00314 */ 00315 PN_EXTERN int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname); 00316 00317 00318 /** Access the configured peer identity. 00319 * 00320 * Return the expected identity of the remote peer, as set by ::pn_ssl_set_peer_hostname. 00321 * 00322 * @param[in] ssl the ssl session. 00323 * @param[out] hostname buffer to hold the null-terminated name string. If null, no string 00324 * is written. 00325 * @param[in,out] bufsize on input set to the number of octets in hostname. On output, set 00326 * to the number of octets needed to hold the value of hostname plus a null byte. Zero if 00327 * no hostname set. 00328 * @return 0 on success. 00329 */ 00330 PN_EXTERN int pn_ssl_get_peer_hostname( pn_ssl_t *ssl, char *hostname, size_t *bufsize ); 00331 00332 /** Get the subject from the peers certificate. 00333 * 00334 * @param[in] ssl the ssl client/server to query. 00335 * @return A null terminated string representing the full subject, 00336 * which is valid until the ssl object is destroyed. 00337 */ 00338 PN_EXTERN const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl); 00339 00340 /** @} */ 00341 00342 #ifdef __cplusplus 00343 } 00344 #endif 00345 00346 #endif /* ssl.h */