summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Steinert <mike.steinert@gmail.com>2012-08-30 16:08:23 -0600
committerAlan Antonuk <alan.antonuk@gmail.com>2013-04-09 15:53:03 -0700
commit09eccb1c0832713f377235c941716007085b47fc (patch)
treebd2124d29547fb740e5b7d6e51870f1a57d43788
parent15a80404bec02e6fbf47108f306f6b3020bc078d (diff)
downloadrabbitmq-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.c11
-rw-r--r--examples/amqps_consumer.c9
-rw-r--r--examples/amqps_exchange_declare.c9
-rw-r--r--examples/amqps_listen.c11
-rw-r--r--examples/amqps_listenq.c11
-rw-r--r--examples/amqps_producer.c11
-rw-r--r--examples/amqps_sendstring.c11
-rw-r--r--examples/amqps_unbind.c11
-rw-r--r--librabbitmq/amqp-openssl.c80
-rw-r--r--librabbitmq/amqp-ssl-socket.h38
-rw-r--r--tools/common.c7
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");