diff options
author | Michael Steinert <mike.steinert@gmail.com> | 2012-08-30 16:08:23 -0600 |
---|---|---|
committer | Alan Antonuk <alan.antonuk@gmail.com> | 2013-04-09 15:53:03 -0700 |
commit | 09eccb1c0832713f377235c941716007085b47fc (patch) | |
tree | bd2124d29547fb740e5b7d6e51870f1a57d43788 | |
parent | 15a80404bec02e6fbf47108f306f6b3020bc078d (diff) | |
download | rabbitmq-c-github-ask-09eccb1c0832713f377235c941716007085b47fc.tar.gz |
Add API to load SSL keys from a buffer
Signed-off-by: Michael Steinert <mike.steinert@gmail.com>
-rw-r--r-- | examples/amqps_bind.c | 11 | ||||
-rw-r--r-- | examples/amqps_consumer.c | 9 | ||||
-rw-r--r-- | examples/amqps_exchange_declare.c | 9 | ||||
-rw-r--r-- | examples/amqps_listen.c | 11 | ||||
-rw-r--r-- | examples/amqps_listenq.c | 11 | ||||
-rw-r--r-- | examples/amqps_producer.c | 11 | ||||
-rw-r--r-- | examples/amqps_sendstring.c | 11 | ||||
-rw-r--r-- | examples/amqps_unbind.c | 11 | ||||
-rw-r--r-- | librabbitmq/amqp-openssl.c | 80 | ||||
-rw-r--r-- | librabbitmq/amqp-ssl-socket.h | 38 | ||||
-rw-r--r-- | tools/common.c | 7 |
11 files changed, 174 insertions, 35 deletions
diff --git a/examples/amqps_bind.c b/examples/amqps_bind.c index 3255e70..04db414 100644 --- a/examples/amqps_bind.c +++ b/examples/amqps_bind.c @@ -75,10 +75,17 @@ int main(int argc, char const * const *argv) { } } + if (argc > 7) { + status = amqp_ssl_socket_set_key(socket, argv[7]); + if (status) { + die("setting client key"); + } + } + if (argc > 8) { - status = amqp_ssl_socket_set_key(socket, argv[7], argv[8]); + status = amqp_ssl_socket_set_cert(socket, argv[8]); if (status) { - die("setting client key/cert"); + die("setting client cert"); } } diff --git a/examples/amqps_consumer.c b/examples/amqps_consumer.c index cb47dff..86c9d9f 100644 --- a/examples/amqps_consumer.c +++ b/examples/amqps_consumer.c @@ -148,12 +148,19 @@ int main(int argc, char const * const *argv) { } if (argc > 4) { - status = amqp_ssl_socket_set_key(socket, argv[5], argv[5]); + status = amqp_ssl_socket_set_key(socket, argv[4]); if (status) { die("setting client key/cert"); } } + if (argc > 5) { + status = amqp_ssl_socket_set_cert(socket, argv[5]); + if (status) { + die("setting client key"); + } + } + status = amqp_socket_open(socket, hostname, port); if (status) { die("opening SSL/TLS connection"); diff --git a/examples/amqps_exchange_declare.c b/examples/amqps_exchange_declare.c index 1310235..12c814b 100644 --- a/examples/amqps_exchange_declare.c +++ b/examples/amqps_exchange_declare.c @@ -73,8 +73,15 @@ int main(int argc, char const * const *argv) { } } + if (argc > 6) { + status = amqp_ssl_socket_set_key(socket, argv[6]); + if (status) { + die("setting client key/cert"); + } + } + if (argc > 7) { - status = amqp_ssl_socket_set_key(socket, argv[6], argv[7]); + status = amqp_ssl_socket_set_cert(socket, argv[7]); if (status) { die("setting client key/cert"); } diff --git a/examples/amqps_listen.c b/examples/amqps_listen.c index c6344bd..876bad9 100644 --- a/examples/amqps_listen.c +++ b/examples/amqps_listen.c @@ -77,10 +77,17 @@ int main(int argc, char const * const *argv) { } } + if (argc > 6) { + status = amqp_ssl_socket_set_key(socket, argv[6]); + if (status) { + die("setting client key"); + } + } + if (argc > 7) { - status = amqp_ssl_socket_set_key(socket, argv[6], argv[7]); + status = amqp_ssl_socket_set_cert(socket, argv[7]); if (status) { - die("setting client key/cert"); + die("setting client cert"); } } diff --git a/examples/amqps_listenq.c b/examples/amqps_listenq.c index 0a9c687..9d910c9 100644 --- a/examples/amqps_listenq.c +++ b/examples/amqps_listenq.c @@ -73,10 +73,17 @@ int main(int argc, char const * const *argv) { } } + if (argc > 5) { + status = amqp_ssl_socket_set_key(socket, argv[5]); + if (status) { + die("setting client key"); + } + } + if (argc > 6) { - status = amqp_ssl_socket_set_key(socket, argv[5], argv[6]); + status = amqp_ssl_socket_set_cert(socket, argv[5]); if (status) { - die("setting client key/cert"); + die("setting client cert"); } } diff --git a/examples/amqps_producer.c b/examples/amqps_producer.c index 43649ad..18f0b3f 100644 --- a/examples/amqps_producer.c +++ b/examples/amqps_producer.c @@ -137,10 +137,17 @@ int main(int argc, char const * const *argv) { } } + if (argc > 6) { + status = amqp_ssl_socket_set_key(socket, argv[6]); + if (status) { + die("setting client key"); + } + } + if (argc > 7) { - status = amqp_ssl_socket_set_key(socket, argv[6], argv[7]); + status = amqp_ssl_socket_set_cert(socket, argv[7]); if (status) { - die("setting client key/cert"); + die("setting client cert"); } } diff --git a/examples/amqps_sendstring.c b/examples/amqps_sendstring.c index a888da8..1133dcf 100644 --- a/examples/amqps_sendstring.c +++ b/examples/amqps_sendstring.c @@ -75,10 +75,17 @@ int main(int argc, char const * const *argv) { } } + if (argc > 7) { + status = amqp_ssl_socket_set_key(socket, argv[7]); + if (status) { + die("setting client key"); + } + } + if (argc > 8) { - status = amqp_ssl_socket_set_key(socket, argv[7], argv[8]); + status = amqp_ssl_socket_set_cert(socket, argv[8]); if (status) { - die("setting client key/cert"); + die("setting client cert"); } } diff --git a/examples/amqps_unbind.c b/examples/amqps_unbind.c index e9f4317..5c8a4b5 100644 --- a/examples/amqps_unbind.c +++ b/examples/amqps_unbind.c @@ -75,10 +75,17 @@ int main(int argc, char const * const *argv) { } } + if (argc > 7) { + status = amqp_ssl_socket_set_key(socket, argv[7]); + if (status) { + die("setting client key"); + } + } + if (argc > 8) { - status = amqp_ssl_socket_set_key(socket, argv[7], argv[8]); + status = amqp_ssl_socket_set_cert(socket, argv[8]); if (status) { - die("setting client key/cert"); + die("setting client cert"); } } diff --git a/librabbitmq/amqp-openssl.c b/librabbitmq/amqp-openssl.c index 4974a11..df158b7 100644 --- a/librabbitmq/amqp-openssl.c +++ b/librabbitmq/amqp-openssl.c @@ -324,27 +324,79 @@ amqp_ssl_socket_set_cacert(amqp_socket_t *base, int amqp_ssl_socket_set_key(amqp_socket_t *base, - const char *key, - const char *cert) + const char *key) { struct amqp_ssl_socket_t *self; if (base->klass != &amqp_ssl_socket_class) { amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); } self = (struct amqp_ssl_socket_t *)base; - if (key && cert) { - int status = SSL_CTX_use_PrivateKey_file(self->ctx, key, - SSL_FILETYPE_PEM); - if (1 != status) { - return -1; - } - status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); - if (1 != status) { - return -1; - } - return 0; + int status = SSL_CTX_use_PrivateKey_file(self->ctx, key, + SSL_FILETYPE_PEM); + if (1 != status) { + return -1; } - return -1; + return 0; +} + +static int +password_cb(AMQP_UNUSED char *buffer, + AMQP_UNUSED int length, + AMQP_UNUSED int rwflag, + AMQP_UNUSED void *user_data) +{ + amqp_abort("don't use password protected keys!"); + return 0; +} + +int +amqp_ssl_socket_set_key_buffer(amqp_socket_t *base, + const void *key, + size_t n) +{ + int status = 0; + BIO *buf = NULL; + RSA *rsa = NULL; + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + buf = BIO_new_mem_buf((void *)key, n); + if (!buf) { + goto error; + } + rsa = PEM_read_bio_RSAPrivateKey(buf, NULL, password_cb, NULL); + if (!rsa) { + goto error; + } + status = SSL_CTX_use_RSAPrivateKey(self->ctx, rsa); + if (1 != status) { + goto error; + } +exit: + BIO_vfree(buf); + RSA_free(rsa); + return status; +error: + status = -1; + goto exit; +} + +int +amqp_ssl_socket_set_cert(amqp_socket_t *base, + const char *cert) +{ + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + int status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); + if (1 != status) { + return -1; + } + return 0; } void diff --git a/librabbitmq/amqp-ssl-socket.h b/librabbitmq/amqp-ssl-socket.h index bea5b75..b6396ed 100644 --- a/librabbitmq/amqp-ssl-socket.h +++ b/librabbitmq/amqp-ssl-socket.h @@ -55,20 +55,48 @@ amqp_ssl_socket_set_cacert(amqp_socket_t *self, const char *cacert); /** - * Set the client key & certificate. + * Set the client key. * * \param [in,out] self An SSL/TLS socket object. * \param [in] key Path to the client key in PEM format. - * \param [in] cert Path to the client certificate in PEM foramt. * - * \return Zero if successful, false otherwise. + * \return Zero if successful, -1 otherwise. */ AMQP_PUBLIC_FUNCTION int AMQP_CALL amqp_ssl_socket_set_key(amqp_socket_t *self, - const char *key, - const char *cert); + const char *key); + +/** + * Set the client key from a buffer. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] key A buffer containing client key in PEM format. + * \param [in] n The length of the buffer. + * + * \return Zero if successful, -1 otherwise. + */ +AMQP_PUBLIC_FUNCTION +int +AMQP_CALL +amqp_ssl_socket_set_key_buffer(amqp_socket_t *self, + const void *key, + size_t n); + +/** + * Set the client certificate. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] cert Path to the client certificate in PEM foramt. + * + * \return Zero if successful, -1 otherwise. + */ +AMQP_PUBLIC_FUNCTION +int +AMQP_CALL +amqp_ssl_socket_set_cert(amqp_socket_t *self, + const char *cert); /** * Enable or disable peer verification. diff --git a/tools/common.c b/tools/common.c index ef8f37b..60d70fb 100644 --- a/tools/common.c +++ b/tools/common.c @@ -335,8 +335,11 @@ amqp_connection_state_t make_connection(void) if (amqp_cacert) { amqp_ssl_socket_set_cacert(socket, amqp_cacert); } - if (amqp_key && amqp_cert) { - amqp_ssl_socket_set_key(socket, amqp_key, amqp_cert); + if (amqp_key) { + amqp_ssl_socket_set_key(socket, amqp_key); + } + if (amqp_cert) { + amqp_ssl_socket_set_cert(socket, amqp_cert); } #else die("librabbitmq was not built with SSL/TLS support"); |