proton  0
ssl.h
Go to the documentation of this file.
1 #ifndef PROTON_SSL_H
2 #define PROTON_SSL_H 1
3 
4 /*
5  *
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements. See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership. The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied. See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  *
23  */
24 
25 #include <proton/import_export.h>
26 #include <proton/type_compat.h>
27 #include <proton/types.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /** @file
34  * API for using SSL with the Transport Layer.
35  *
36  * A Transport may be configured to use SSL for encryption and/or authentication. A
37  * Transport can be configured as either an "SSL client" or an "SSL server". An SSL
38  * client is the party that proactively establishes a connection to an SSL server. An SSL
39  * server is the party that accepts a connection request from a remote SSL client.
40  *
41  * This SSL implementation defines the following objects:
42 
43  * @li A top-level object that stores the configuration used by one or more SSL
44  * sessions (pn_ssl_domain_t).
45  * @li A per-connection SSL session object that performs the encryption/authentication
46  * associated with the transport (pn_ssl_t).
47  * @li The encryption parameters negotiated for the SSL session (pn_ssl_state_t).
48  *
49  * A pn_ssl_domain_t object must be created and configured before an SSL session can be
50  * established. The pn_ssl_domain_t is used to construct an SSL session (pn_ssl_t). The
51  * session "adopts" its configuration from the pn_ssl_domain_t that was used to create it.
52  * For example, pn_ssl_domain_t can be configured as either a "client" or a "server". SSL
53  * sessions constructed from this domain will perform the corresponding role (either
54  * client or server).
55  *
56  * If either an SSL server or client needs to identify itself with the remote node, it
57  * must have its SSL certificate configured (see ::pn_ssl_domain_set_credentials()).
58  *
59  * If either an SSL server or client needs to verify the identity of the remote node, it
60  * must have its database of trusted CAs configured (see ::pn_ssl_domain_set_trusted_ca_db()).
61  *
62  * An SSL server connection may allow the remote client to connect without SSL (eg. "in
63  * the clear"), see ::pn_ssl_domain_allow_unsecured_client().
64  *
65  * The level of verification required of the remote may be configured (see
66  * ::pn_ssl_domain_set_peer_authentication)
67  *
68  * Support for SSL Client Session resume is provided (see ::pn_ssl_init,
69  * ::pn_ssl_resume_status).
70  *
71  * @defgroup ssl SSL
72  * @ingroup transport
73  * @{
74  */
75 
77 typedef struct pn_ssl_t pn_ssl_t;
78 
79 /** Determines the type of SSL endpoint. */
80 typedef enum {
81  PN_SSL_MODE_CLIENT=1, /**< Local connection endpoint is an SSL client */
82  PN_SSL_MODE_SERVER /**< Local connection endpoint is an SSL server */
84 
85 /** Indicates whether an SSL session has been resumed. */
86 typedef enum {
87  PN_SSL_RESUME_UNKNOWN, /**< Session resume state unknown/not supported */
88  PN_SSL_RESUME_NEW, /**< Session renegotiated - not resumed */
89  PN_SSL_RESUME_REUSED /**< Session resumed from previous session. */
91 
92 /** Tests for SSL implementation present
93  *
94  * @return true if we support SSL, false if not
95  */
96 PN_EXTERN bool pn_ssl_present( void );
97 
98 /** Create an SSL configuration domain
99  *
100  * This method allocates an SSL domain object. This object is used to hold the SSL
101  * configuration for one or more SSL sessions. The SSL session object (pn_ssl_t) is
102  * allocated from this object.
103  *
104  * @param[in] mode the role, client or server, assumed by all SSL sessions created
105  * with this domain.
106  * @return a pointer to the SSL domain, if SSL support is present.
107  */
108 PN_EXTERN pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode);
109 
110 /** Release an SSL configuration domain
111  *
112  * This method frees an SSL domain object allocated by ::pn_ssl_domain.
113  * @param[in] domain the domain to destroy.
114  */
116 
117 /** Set the certificate that identifies the local node to the remote.
118  *
119  * This certificate establishes the identity for the local node for all SSL sessions
120  * created from this domain. It will be sent to the remote if the remote needs to verify
121  * the identity of this node. This may be used for both SSL servers and SSL clients (if
122  * client authentication is required by the server).
123  *
124  * @note This setting effects only those pn_ssl_t objects created after this call
125  * returns. pn_ssl_t objects created before invoking this method will use the domain's
126  * previous setting.
127  *
128  * @param[in] domain the ssl domain that will use this certificate.
129  * @param[in] credential_1 specifier for the file/database containing the identifying
130  * certificate. For Openssl users, this is a PEM file. For Windows SChannel users, this is
131  * the PKCS#12 file or system store.
132  * @param[in] credential_2 an optional key to access the identifying certificate. For
133  * Openssl users, this is an optional PEM file containing the private key used to sign the
134  * certificate. For Windows SChannel users, this is the friendly name of the
135  * self-identifying certificate if there are multiple certificates in the store.
136  * @param[in] password the password used to sign the key, else NULL if key is not
137  * protected.
138  * @return 0 on success
139  */
141  const char *credential_1,
142  const char *credential_2,
143  const char *password);
144 
145 /** Configure the set of trusted CA certificates used by this domain to verify peers.
146  *
147  * If the local SSL client/server needs to verify the identity of the remote, it must
148  * validate the signature of the remote's certificate. This function sets the database of
149  * trusted CAs that will be used to verify the signature of the remote's certificate.
150  *
151  * @note This setting effects only those pn_ssl_t objects created after this call
152  * returns. pn_ssl_t objects created before invoking this method will use the domain's
153  * previous setting.
154  *
155  * @param[in] domain the ssl domain that will use the database.
156  * @param[in] certificate_db database of trusted CAs, used to authenticate the peer.
157  * @return 0 on success
158  */
160  const char *certificate_db);
161 
162 /** Determines the level of peer validation.
163  *
164  * ANONYMOUS_PEER does not require a valid certificate, and permits use of ciphers that
165  * do not provide authentication.
166  *
167  * VERIFY_PEER will only connect to those peers that provide a valid identifying
168  * certificate signed by a trusted CA and are using an authenticated cipher.
169  *
170  * VERIFY_PEER_NAME is like VERIFY_PEER, but also requires the peer's identity as
171  * contained in the certificate to be valid (see ::pn_ssl_set_peer_hostname).
172  *
173  * ANONYMOUS_PEER is configured by default.
174  */
175 typedef enum {
176  PN_SSL_VERIFY_NULL=0, /**< internal use only */
177  PN_SSL_VERIFY_PEER, /**< require peer to provide a valid identifying certificate */
178  PN_SSL_ANONYMOUS_PEER, /**< do not require a certificate nor cipher authorization */
179  PN_SSL_VERIFY_PEER_NAME /**< require valid certificate and matching name */
181 
182 /** Configure the level of verification used on the peer certificate.
183  *
184  * This method controls how the peer's certificate is validated, if at all. By default,
185  * neither servers nor clients attempt to verify their peers (PN_SSL_ANONYMOUS_PEER).
186  * Once certificates and trusted CAs are configured, peer verification can be enabled.
187  *
188  * @note In order to verify a peer, a trusted CA must be configured. See
189  * ::pn_ssl_domain_set_trusted_ca_db().
190  *
191  * @note Servers must provide their own certificate when verifying a peer. See
192  * ::pn_ssl_domain_set_credentials().
193  *
194  * @note This setting effects only those pn_ssl_t objects created after this call
195  * returns. pn_ssl_t objects created before invoking this method will use the domain's
196  * previous setting.
197  *
198  * @param[in] domain the ssl domain to configure.
199  * @param[in] mode the level of validation to apply to the peer
200  * @param[in] trusted_CAs path to a database of trusted CAs that the server will advertise
201  * to the peer client if the server has been configured to verify its peer.
202  * @return 0 on success
203  */
205  const pn_ssl_verify_mode_t mode,
206  const char *trusted_CAs);
207 
208 /** Permit a server to accept connection requests from non-SSL clients.
209  *
210  * This configures the server to "sniff" the incoming client data stream, and dynamically
211  * determine whether SSL/TLS is being used. This option is disabled by default: only
212  * clients using SSL/TLS are accepted.
213  *
214  * @param[in] domain the domain (server) that will accept the client connections.
215  * @return 0 on success
216  */
218 
219 /** Create a new SSL session object associated with a transport.
220  *
221  * A transport must have an SSL object in order to "speak" SSL over its connection. This
222  * method allocates an SSL object associates it with the transport.
223  *
224  * @param[in] transport the transport that will own the new SSL session.
225  * @return a pointer to the SSL object configured for this transport. Returns NULL if
226  * no SSL session is associated with the transport.
227  */
229 
230 /** Initialize an SSL session.
231  *
232  * This method configures an SSL object using the configuration provided by the given
233  * domain.
234  *
235  * @param[in] ssl the ssl session to configured.
236  * @param[in] domain the ssl domain used to configure the SSL session.
237  * @param[in] session_id if supplied, attempt to resume a previous SSL
238  * session that used the same session_id. If no previous SSL session
239  * is available, a new session will be created using the session_id
240  * and stored for future session restore (see ::::pn_ssl_resume_status).
241  * @return 0 on success, else an error code.
242  */
243 PN_EXTERN int pn_ssl_init( pn_ssl_t *ssl,
244  pn_ssl_domain_t *domain,
245  const char *session_id);
246 
247 /** Get the name of the Cipher that is currently in use.
248  *
249  * Gets a text description of the cipher that is currently active, or returns FALSE if SSL
250  * is not active (no cipher). Note that the cipher in use may change over time due to
251  * renegotiation or other changes to the SSL state.
252  *
253  * @param[in] ssl the ssl client/server to query.
254  * @param[in,out] buffer buffer of size bytes to hold cipher name
255  * @param[in] size maximum number of bytes in buffer.
256  * @return True if cipher name written to buffer, False if no cipher in use.
257  */
258 PN_EXTERN bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *buffer, size_t size);
259 
260 /** Get the SSF (security strength factor) of the Cipher that is currently in use.
261  *
262  * @param[in] ssl the ssl client/server to query.
263  * @return the ssf, note that 0 means no security.
264  */
266 
267 /** Get the name of the SSL protocol that is currently in use.
268  *
269  * Gets a text description of the SSL protocol that is currently active, or returns FALSE if SSL
270  * is not active. Note that the protocol may change over time due to renegotiation.
271  *
272  * @param[in] ssl the ssl client/server to query.
273  * @param[in,out] buffer buffer of size bytes to hold the version identifier
274  * @param[in] size maximum number of bytes in buffer.
275  * @return True if the version information was written to buffer, False if SSL connection
276  * not ready.
277  */
278 PN_EXTERN bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size);
279 
280 /** Check whether the state has been resumed.
281  *
282  * Used for client session resume. When called on an active session, indicates whether
283  * the state has been resumed from a previous session.
284  *
285  * @note This is a best-effort service - there is no guarantee that the remote server will
286  * accept the resumed parameters. The remote server may choose to ignore these
287  * parameters, and request a re-negotiation instead.
288  *
289  * @param[in] ssl the ssl session to check
290  * @return status code indicating whether or not the session has been resumed.
291  */
292 PN_EXTERN pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl );
293 
294 /** Set the expected identity of the remote peer.
295  *
296  * By default, SSL will use the hostname associated with the connection that
297  * the transport is bound to (see ::pn_connection_set_hostname). This method
298  * allows the caller to override that default.
299  *
300  * The hostname is used for two purposes: 1) when set on an SSL client, it is sent to the
301  * server during the handshake (if Server Name Indication is supported), and 2) it is used
302  * to check against the identifying name provided in the peer's certificate. If the
303  * supplied name does not exactly match a SubjectAltName (type DNS name), or the
304  * CommonName entry in the peer's certificate, the peer is considered unauthenticated
305  * (potential imposter), and the SSL connection is aborted.
306  *
307  * @note Verification of the hostname is only done if PN_SSL_VERIFY_PEER_NAME is enabled.
308  * See ::pn_ssl_domain_set_peer_authentication.
309  *
310  * @param[in] ssl the ssl session.
311  * @param[in] hostname the expected identity of the remote. Must conform to the syntax as
312  * given in RFC1034, Section 3.5.
313  * @return 0 on success.
314  */
315 PN_EXTERN int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname);
316 
317 
318 /** Access the configured peer identity.
319  *
320  * Return the expected identity of the remote peer, as set by ::pn_ssl_set_peer_hostname.
321  *
322  * @param[in] ssl the ssl session.
323  * @param[out] hostname buffer to hold the null-terminated name string. If null, no string
324  * is written.
325  * @param[in,out] bufsize on input set to the number of octets in hostname. On output, set
326  * to the number of octets needed to hold the value of hostname plus a null byte. Zero if
327  * no hostname set.
328  * @return 0 on success.
329  */
330 PN_EXTERN int pn_ssl_get_peer_hostname( pn_ssl_t *ssl, char *hostname, size_t *bufsize );
331 
332 /** Get the subject from the peers certificate.
333  *
334  * @param[in] ssl the ssl client/server to query.
335  * @return A null terminated string representing the full subject,
336  * which is valid until the ssl object is destroyed.
337  */
339 
340 /**
341  * Enumeration identifying the sub fields of the subject field in the ssl certificate.
342  */
343 typedef enum {
351 
352 
353 /**
354  * Enumeration identifying hashing algorithm.
355  */
356 typedef enum {
357  PN_SSL_SHA1, /* Produces hash that is 20 bytes long */
358  PN_SSL_SHA256, /* Produces hash that is 32 bytes long */
359  PN_SSL_SHA512, /* Produces hash that is 64 bytes long */
360  PN_SSL_MD5 /* Produces hash that is 16 bytes long */
362 
363 /**
364  * Get the fingerprint of the certificate. The certificate fingerprint (as displayed in the Fingerprints section when
365  * looking at a certificate with say the Firefox browser) is the hexadecimal hash of the entire certificate.
366  * The fingerprint is not part of the certificate, rather it is computed from the certificate and can be used to uniquely identify a certificate.
367  * @param[in] ssl0 the ssl client/server to query
368  * @param[in] fingerprint char pointer. The certificate fingerprint (in hex format) will be populated in this array.
369  * If sha1 is the digest name, the fingerprint is 41 characters long (40 + 1 '\0' character), 65 characters long for
370  * sha256 and 129 characters long for sha512 and 33 characters for md5.
371  * @param[in] fingerprint_length - Must be at >= 33 for md5, >= 41 for sha1, >= 65 for sha256 and >=129 for sha512.
372  * @param[in] hash_alg the hash algorithm to use. Must be of type pn_ssl_hash_alg (currently supports sha1, sha256, sha512 and md5)
373  * @return error code - Returns 0 on success. Return a value less than zero if there were any errors. Upon execution of this function,
374  * char *fingerprint will contain the appropriate null terminated hex fingerprint
375  */
377  char *fingerprint,
378  size_t fingerprint_length,
379  pn_ssl_hash_alg hash_alg);
380 
381 /**
382  * 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 -
383  * C = ISO3166 two character country code
384  * ST = state or province
385  * L = Locality; generally means city
386  * O = Organization - Company Name
387  * OU = Organization Unit - division or unit
388  * CN = CommonName
389  * @param[in] ssl0 the ssl client/server to query
390  * @param[in] field The enumeration pn_ssl_cert_subject_subfield representing the required sub field.
391  * @return A null terminated string which contains the requested sub field value which is valid until the ssl object is destroyed.
392  */
393 PN_EXTERN const char* pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subject_subfield field);
394 
395 /** @} */
396 
397 #ifdef __cplusplus
398 }
399 #endif
400 
401 #endif /* ssl.h */
PN_EXTERN pn_ssl_resume_status_t pn_ssl_resume_status(pn_ssl_t *ssl)
Check whether the state has been resumed.
Definition: ssl.h:359
PN_EXTERN int pn_ssl_get_ssf(pn_ssl_t *ssl)
Get the SSF (security strength factor) of the Cipher that is currently in use.
PN_EXTERN int pn_ssl_domain_set_credentials(pn_ssl_domain_t *domain, const char *credential_1, const char *credential_2, const char *password)
Set the certificate that identifies the local node to the remote.
PN_EXTERN int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain)
Permit a server to accept connection requests from non-SSL clients.
PN_EXTERN bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size)
Get the name of the SSL protocol that is currently in use.
struct pn_transport_t pn_transport_t
An AMQP Transport object.
Definition: types.h:256
require valid certificate and matching name
Definition: ssl.h:179
PN_EXTERN int pn_ssl_set_peer_hostname(pn_ssl_t *ssl, const char *hostname)
Set the expected identity of the remote peer.
require peer to provide a valid identifying certificate
Definition: ssl.h:177
pn_ssl_cert_subject_subfield
Enumeration identifying the sub fields of the subject field in the ssl certificate.
Definition: ssl.h:343
pn_ssl_verify_mode_t
Determines the level of peer validation.
Definition: ssl.h:175
PN_EXTERN pn_ssl_t * pn_ssl(pn_transport_t *transport)
Create a new SSL session object associated with a transport.
Session resume state unknown/not supported.
Definition: ssl.h:87
#define PN_EXTERN
Definition: import_export.h:53
pn_ssl_mode_t
Determines the type of SSL endpoint.
Definition: ssl.h:80
Definition: ssl.h:358
pn_ssl_resume_status_t
Indicates whether an SSL session has been resumed.
Definition: ssl.h:86
struct pn_ssl_domain_t pn_ssl_domain_t
Definition: ssl.h:76
PN_EXTERN const char * pn_ssl_get_remote_subject(pn_ssl_t *ssl)
Get the subject from the peers certificate.
Session resumed from previous session.
Definition: ssl.h:89
PN_EXTERN const char * pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subject_subfield field)
Returns a char pointer that contains the value of the sub field of the subject field in the ssl certi...
struct pn_ssl_t pn_ssl_t
Definition: ssl.h:77
PN_EXTERN void pn_ssl_domain_free(pn_ssl_domain_t *domain)
Release an SSL configuration domain.
PN_EXTERN bool pn_ssl_present(void)
Tests for SSL implementation present.
PN_EXTERN pn_ssl_domain_t * pn_ssl_domain(pn_ssl_mode_t mode)
Create an SSL configuration domain.
PN_EXTERN int pn_ssl_get_peer_hostname(pn_ssl_t *ssl, char *hostname, size_t *bufsize)
Access the configured peer identity.
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 level of verification used on the peer certificate.
Local connection endpoint is an SSL server.
Definition: ssl.h:82
PN_EXTERN bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *buffer, size_t size)
Get the name of the Cipher that is currently in use.
Session renegotiated - not resumed.
Definition: ssl.h:88
Definition: ssl.h:349
Definition: ssl.h:357
Local connection endpoint is an SSL client.
Definition: ssl.h:81
pn_ssl_hash_alg
Enumeration identifying hashing algorithm.
Definition: ssl.h:356
internal use only
Definition: ssl.h:176
Definition: ssl.h:360
PN_EXTERN int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain, const char *certificate_db)
Configure the set of trusted CA certificates used by this domain to verify peers. ...
PN_EXTERN int pn_ssl_init(pn_ssl_t *ssl, pn_ssl_domain_t *domain, const char *session_id)
Initialize an SSL session.
do not require a certificate nor cipher authorization
Definition: ssl.h:178
PN_EXTERN int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl0, char *fingerprint, size_t fingerprint_length, pn_ssl_hash_alg hash_alg)
Get the fingerprint of the certificate.