You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/10/19 12:40:23 UTC
[37/50] qpid-proton git commit: PROTON-1620: set locking function for
old versions of openssl
PROTON-1620: set locking function for old versions of openssl
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/434a2e77
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/434a2e77
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/434a2e77
Branch: refs/heads/go1
Commit: 434a2e7731b757ac6a303725122d811aa90ff023
Parents: a49e36d
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 16 16:53:48 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 17 11:04:55 2017 +0100
----------------------------------------------------------------------
examples/c/CMakeLists.txt | 2 +-
examples/c/broker.c | 28 +-
examples/c/example_test.py | 6 +
examples/c/send-ssl.c | 229 ++++++++++++
examples/c/ssl_certs/README.txt | 24 ++
examples/c/ssl_certs/tclient-certificate.p12 | Bin 0 -> 1032 bytes
examples/c/ssl_certs/tclient-certificate.pem | 19 +
examples/c/ssl_certs/tclient-full.p12 | Bin 0 -> 2476 bytes
examples/c/ssl_certs/tclient-private-key.pem | 30 ++
examples/c/ssl_certs/tserver-certificate.p12 | Bin 0 -> 1032 bytes
examples/c/ssl_certs/tserver-certificate.pem | 19 +
examples/c/ssl_certs/tserver-full.p12 | Bin 0 -> 2476 bytes
examples/c/ssl_certs/tserver-private-key.pem | 30 ++
proton-c/src/ssl/openssl.c | 406 +++++++++++++---------
proton-c/src/tests/proactor.c | 1 -
15 files changed, 627 insertions(+), 167 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt
index 4bfff2d..48ae9b2 100644
--- a/examples/c/CMakeLists.txt
+++ b/examples/c/CMakeLists.txt
@@ -34,7 +34,7 @@ else()
set(test_path "${CMAKE_CURRENT_BINARY_DIR}:$ENV{PATH}")
endif()
-foreach (name broker send receive direct send-abort)
+foreach (name broker send receive direct send-abort send-ssl)
add_executable(c-${name} ${name}.c)
target_link_libraries(c-${name} ${Proton_Proactor_LIBRARIES} ${Proton_Core_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
set_target_properties(c-${name} PROPERTIES
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/broker.c
----------------------------------------------------------------------
diff --git a/examples/c/broker.c b/examples/c/broker.c
index d6cb753..541fbff 100644
--- a/examples/c/broker.c
+++ b/examples/c/broker.c
@@ -23,12 +23,27 @@
#include <proton/listener.h>
#include <proton/proactor.h>
#include <proton/sasl.h>
+#include <proton/ssl.h>
#include <proton/transport.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+/* The ssl_certs subdir must be in the current directory for an ssl-enabled broker */
+#define SSL_FILE(NAME) "ssl_certs/" NAME
+#define SSL_PW "tserverpw"
+/* Windows vs. OpenSSL certificates */
+#if defined(_WIN32)
+# define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.p12")
+# define SET_CREDENTIALS(DOMAIN, NAME) \
+ pn_ssl_domain_set_credentials(DOMAIN, SSL_FILE(NAME "-full.p12"), "", SSL_PW)
+#else
+# define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.pem")
+# define SET_CREDENTIALS(DOMAIN, NAME) \
+ pn_ssl_domain_set_credentials(DOMAIN, CERTIFICATE(NAME), SSL_FILE(NAME "-private-key.pem"), SSL_PW)
+#endif
+
/* Simple re-sizable vector that acts as a queue */
#define VEC(T) struct { T* data; size_t len, cap; }
@@ -199,6 +214,7 @@ typedef struct broker_t {
const char *container_id; /* AMQP container-id */
queues_t queues;
bool finished;
+ pn_ssl_domain_t *ssl_domain;
} broker_t;
void broker_stop(broker_t *b) {
@@ -283,10 +299,15 @@ static void handle(broker_t* b, pn_event_t* e) {
break;
case PN_CONNECTION_BOUND: {
- /* Turn off security */
+ /* Allow anonymous connections by SASL */
pn_transport_t *t = pn_connection_transport(c);
pn_transport_require_auth(t, false);
pn_sasl_allowed_mechs(pn_sasl(t), "ANONYMOUS");
+ /* Accept SSL connections if possible, but also plain connections.
+ See the call to pn_ssl_domain_allow_unsecured_client() in main() */
+ if (b->ssl_domain) {
+ pn_ssl_init(pn_ssl(pn_event_transport(e)), b->ssl_domain, NULL);
+ }
break;
}
case PN_CONNECTION_REMOTE_OPEN: {
@@ -427,7 +448,9 @@ int main(int argc, char **argv) {
queues_init(&b.queues);
b.container_id = argv[0];
b.threads = 4;
-
+ b.ssl_domain = pn_ssl_domain(PN_SSL_MODE_SERVER);
+ SET_CREDENTIALS(b.ssl_domain, "tserver");
+ pn_ssl_domain_allow_unsecured_client(b.ssl_domain); /* Allow SSL and plain connections */
{
/* Listen on addr */
char addr[PN_MAX_ADDR];
@@ -449,6 +472,7 @@ int main(int argc, char **argv) {
}
pn_proactor_free(b.proactor);
free(threads);
+ pn_ssl_domain_free(b.ssl_domain);
return 0;
}
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/example_test.py
----------------------------------------------------------------------
diff --git a/examples/c/example_test.py b/examples/c/example_test.py
index 9cd0b13..31d941f 100644
--- a/examples/c/example_test.py
+++ b/examples/c/example_test.py
@@ -116,5 +116,11 @@ class CExampleTest(ProcTestCase):
self.maxDiff = None
self.assertMultiLineEqual(expect, d.wait_exit())
+ def test_send_ssl_receive(self):
+ """Send first then receive"""
+ with Broker(self) as b:
+ self.assertEqual(send_expect(), self.runex("send-ssl", b.port))
+ self.assertMultiLineEqual(receive_expect(), self.runex("receive", b.port))
+
if __name__ == "__main__":
unittest.main()
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/send-ssl.c
----------------------------------------------------------------------
diff --git a/examples/c/send-ssl.c b/examples/c/send-ssl.c
new file mode 100644
index 0000000..8e0722e
--- /dev/null
+++ b/examples/c/send-ssl.c
@@ -0,0 +1,229 @@
+/*
+ *
+ * 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/connection.h>
+#include <proton/condition.h>
+#include <proton/delivery.h>
+#include <proton/link.h>
+#include <proton/message.h>
+#include <proton/proactor.h>
+#include <proton/session.h>
+#include <proton/ssl.h>
+#include <proton/transport.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct app_data_t {
+ const char *host, *port;
+ const char *amqp_address;
+ const char *container_id;
+ int message_count;
+
+ pn_proactor_t *proactor;
+ pn_rwbytes_t message_buffer;
+ int sent;
+ int acknowledged;
+ pn_ssl_domain_t *ssl_domain;
+} app_data_t;
+
+static int exit_code = 0;
+
+/* Note must be run in the current directory to find certificate files */
+#define SSL_FILE(NAME) CMAKE_CURRENT_SOURCE_DIR "/ssl_certs/" NAME
+#define SSL_PW "tclientpw"
+/* Windows vs. OpenSSL certificates */
+#if defined(_WIN32)
+# define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.p12")
+# define SET_CREDENTIALS(DOMAIN, NAME) \
+ pn_ssl_domain_set_credentials(DOMAIN, SSL_FILE(NAME "-full.p12"), "", SSL_PW)
+#else
+# define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.pem")
+# define SET_CREDENTIALS(DOMAIN, NAME) \
+ pn_ssl_domain_set_credentials(DOMAIN, CERTIFICATE(NAME), SSL_FILE(NAME "-private-key.pem"), SSL_PW)
+#endif
+
+
+static void check_condition(pn_event_t *e, pn_condition_t *cond) {
+ if (pn_condition_is_set(cond)) {
+ fprintf(stderr, "%s: %s: %s\n", pn_event_type_name(pn_event_type(e)),
+ pn_condition_get_name(cond), pn_condition_get_description(cond));
+ pn_connection_close(pn_event_connection(e));
+ exit_code = 1;
+ }
+}
+
+/* Create a message with a map { "sequence" : number } encode it and return the encoded buffer. */
+static pn_bytes_t encode_message(app_data_t* app) {
+ /* Construct a message with the map { "sequence": app.sent } */
+ pn_message_t* message = pn_message();
+ pn_data_t* body = pn_message_body(message);
+ pn_data_put_int(pn_message_id(message), app->sent); /* Set the message_id also */
+ pn_data_put_map(body);
+ pn_data_enter(body);
+ pn_data_put_string(body, pn_bytes(sizeof("sequence")-1, "sequence"));
+ pn_data_put_int(body, app->sent); /* The sequence number */
+ pn_data_exit(body);
+
+ /* encode the message, expanding the encode buffer as needed */
+ if (app->message_buffer.start == NULL) {
+ static const size_t initial_size = 128;
+ app->message_buffer = pn_rwbytes(initial_size, (char*)malloc(initial_size));
+ }
+ /* app->message_buffer is the total buffer space available. */
+ /* mbuf wil point at just the portion used by the encoded message */
+ {
+ pn_rwbytes_t mbuf = pn_rwbytes(app->message_buffer.size, app->message_buffer.start);
+ int status = 0;
+ while ((status = pn_message_encode(message, mbuf.start, &mbuf.size)) == PN_OVERFLOW) {
+ app->message_buffer.size *= 2;
+ app->message_buffer.start = (char*)realloc(app->message_buffer.start, app->message_buffer.size);
+ mbuf.size = app->message_buffer.size;
+ mbuf.start = app->message_buffer.start;
+ }
+ if (status != 0) {
+ fprintf(stderr, "error encoding message: %s\n", pn_error_text(pn_message_error(message)));
+ exit(1);
+ }
+ pn_message_free(message);
+ return pn_bytes(mbuf.size, mbuf.start);
+ }
+}
+
+/* Returns true to continue, false if finished */
+static bool handle(app_data_t* app, pn_event_t* event) {
+ switch (pn_event_type(event)) {
+
+ case PN_CONNECTION_INIT: {
+ pn_connection_t* c = pn_event_connection(event);
+ pn_session_t* s = pn_session(pn_event_connection(event));
+ pn_connection_set_container(c, app->container_id);
+ pn_connection_open(c);
+ pn_session_open(s);
+ {
+ pn_link_t* l = pn_sender(s, "my_sender");
+ pn_terminus_set_address(pn_link_target(l), app->amqp_address);
+ pn_link_open(l);
+ break;
+ }
+ }
+
+ case PN_CONNECTION_BOUND: {
+ int err = pn_ssl_init(pn_ssl(pn_event_transport(event)), app->ssl_domain, NULL);
+ if (err) fprintf(stderr, "error encoding message: %s\n", pn_code(err));
+ }
+
+ case PN_LINK_FLOW: {
+ /* The peer has given us some credit, now we can send messages */
+ pn_link_t *sender = pn_event_link(event);
+ while (pn_link_credit(sender) > 0 && app->sent < app->message_count) {
+ ++app->sent;
+ /* Use sent counter as unique delivery tag. */
+ pn_delivery(sender, pn_dtag((const char *)&app->sent, sizeof(app->sent)));
+ {
+ pn_bytes_t msgbuf = encode_message(app);
+ pn_link_send(sender, msgbuf.start, msgbuf.size);
+ }
+ pn_link_advance(sender);
+ }
+ break;
+ }
+
+ case PN_DELIVERY: {
+ /* We received acknowledgedment from the peer that a message was delivered. */
+ pn_delivery_t* d = pn_event_delivery(event);
+ if (pn_delivery_remote_state(d) == PN_ACCEPTED) {
+ if (++app->acknowledged == app->message_count) {
+ printf("%d messages sent and acknowledged\n", app->acknowledged);
+ pn_connection_close(pn_event_connection(event));
+ /* Continue handling events till we receive TRANSPORT_CLOSED */
+ }
+ } else {
+ fprintf(stderr, "unexpected delivery state %d\n", (int)pn_delivery_remote_state(d));
+ pn_connection_close(pn_event_connection(event));
+ exit_code=1;
+ }
+ break;
+ }
+
+ case PN_TRANSPORT_CLOSED:
+ check_condition(event, pn_transport_condition(pn_event_transport(event)));
+ break;
+
+ case PN_CONNECTION_REMOTE_CLOSE:
+ check_condition(event, pn_connection_remote_condition(pn_event_connection(event)));
+ pn_connection_close(pn_event_connection(event));
+ break;
+
+ case PN_SESSION_REMOTE_CLOSE:
+ check_condition(event, pn_session_remote_condition(pn_event_session(event)));
+ pn_connection_close(pn_event_connection(event));
+ break;
+
+ case PN_LINK_REMOTE_CLOSE:
+ case PN_LINK_REMOTE_DETACH:
+ check_condition(event, pn_link_remote_condition(pn_event_link(event)));
+ pn_connection_close(pn_event_connection(event));
+ break;
+
+ case PN_PROACTOR_INACTIVE:
+ return false;
+
+ default: break;
+ }
+ return true;
+}
+
+void run(app_data_t *app) {
+ /* Loop and handle events */
+ do {
+ pn_event_batch_t *events = pn_proactor_wait(app->proactor);
+ pn_event_t *e;
+ for (e = pn_event_batch_next(events); e; e = pn_event_batch_next(events)) {
+ if (!handle(app, e)) {
+ return;
+ }
+ }
+ pn_proactor_done(app->proactor, events);
+ } while(true);
+}
+
+int main(int argc, char **argv) {
+ struct app_data_t app = {0};
+ char addr[PN_MAX_ADDR];
+
+ app.container_id = argv[0]; /* Should be unique */
+ app.host = (argc > 1) ? argv[1] : "";
+ app.port = (argc > 2) ? argv[2] : "amqp";
+ app.amqp_address = (argc > 3) ? argv[3] : "examples";
+ app.message_count = (argc > 4) ? atoi(argv[4]) : 10;
+ app.ssl_domain = pn_ssl_domain(PN_SSL_MODE_CLIENT);
+
+ app.proactor = pn_proactor();
+ pn_proactor_addr(addr, sizeof(addr), app.host, app.port);
+ pn_proactor_connect(app.proactor, pn_connection(), addr);
+ run(&app);
+
+ pn_ssl_domain_free(app.ssl_domain);
+ pn_proactor_free(app.proactor);
+ free(app.message_buffer.start);
+ return exit_code;
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/README.txt
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/README.txt b/examples/c/ssl_certs/README.txt
new file mode 100644
index 0000000..9a8a4f9
--- /dev/null
+++ b/examples/c/ssl_certs/README.txt
@@ -0,0 +1,24 @@
+This directory contains basic self signed test certificates for use by
+proton examples.
+
+The ".pem" files are in the format expected by proton implementations
+using OpenSSL. The ".p12" file are for Windows implementations using
+SChannel.
+
+The commands used to generate the certificates follow.
+
+
+make_pn_cert()
+{
+ name=$1
+ subject=$2
+ passwd=$3
+ # create the pem files
+ openssl req -newkey rsa:2048 -keyout $name-private-key.pem -out $name-certificate.pem -subj $subject -passout pass:$passwd -x509 -days 3650
+ # create the p12 files
+ openssl pkcs12 -export -out $name-full.p12 -passin pass:$passwd -passout pass:$passwd -inkey $name-private-key.pem -in $name-certificate.pem -name $name
+ openssl pkcs12 -export -out $name-certificate.p12 -in $name-certificate.pem -name $name -nokeys -passout pass:
+}
+
+make_pn_cert tserver /CN=test_server/OU=proton_test tserverpw
+make_pn_cert tclient /CN=test_client/OU=proton_test tclientpw
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tclient-certificate.p12
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tclient-certificate.p12 b/examples/c/ssl_certs/tclient-certificate.p12
new file mode 100644
index 0000000..4d0e000
Binary files /dev/null and b/examples/c/ssl_certs/tclient-certificate.p12 differ
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tclient-certificate.pem
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tclient-certificate.pem b/examples/c/ssl_certs/tclient-certificate.pem
new file mode 100644
index 0000000..8088e2e
--- /dev/null
+++ b/examples/c/ssl_certs/tclient-certificate.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDKzCCAhOgAwIBAgIJAIV7frIjftgcMA0GCSqGSIb3DQEBCwUAMCwxFDASBgNV
+BAMMC3Rlc3RfY2xpZW50MRQwEgYDVQQLDAtwcm90b25fdGVzdDAeFw0xNTExMjcx
+ODEwMzlaFw0yNTExMjQxODEwMzlaMCwxFDASBgNVBAMMC3Rlc3RfY2xpZW50MRQw
+EgYDVQQLDAtwcm90b25fdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAPCIS4qUdOtQplUxZ6WW0LXcvosqFP6qOiCARLSEWpR3B8bq213rzefwwfcM
+4TtMr88bP+huLKmlyMfwpl8yB88eXkscPgaAce2zk24urWkFXKSQ6GPitWBLGqBa
+V+W0wJ4mfW7MwefVslWfGXI381QEUlBHjkFG30AtzMMTRj2GK2JqUlRXZPljGyB7
+WcXwxcoS+HkKV7FtHWSkLAzyXwQ9vsCUEYdWTUaGXfCUNRSRV7h1LIANbu03NxV0
+XdEl7WXcr7tuTw3axeUGhRFVhLegrxKLuZTTno4aAJnEr8uaDzjxvXnv3Ne2igvy
+gRfZgOMx+XrZEob9OpAoRghQt4cCAwEAAaNQME4wHQYDVR0OBBYEFE4vbyiM0RjG
+TLMLLGGhMZE/5x1GMB8GA1UdIwQYMBaAFE4vbyiM0RjGTLMLLGGhMZE/5x1GMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAErr/rvLS9Ig0UCMwh1J1lA9
+/gvXf93iIK/SjrFIAqYRmfZxg4husfoes8t2hFUeuqoH05TuSOoXG8p8DpgTSGmF
+jAFe+T90vJZTm0oqZkkkI/hdzjGQoHURRp9/O2Z/lm39KSKGVAN5pUWCUDi/G5iS
+P9LZPJN6a5syXMrR6x62IPxAXowlpXkRghKClF3zPOaOBTzT1V27EkI8IEgC+p45
+246EooLnw8ibB+ucNc3KHNzpgKGVd/622+I+Q5eg9AT9PLFttP+R2ECsrVDDPYuA
+p0qaSnwgeozj/d6K3FOgKKEKbzBmpWgkv0jdcVk18aPMHypI/RDtZ/+3ET2Ksi8=
+-----END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tclient-full.p12
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tclient-full.p12 b/examples/c/ssl_certs/tclient-full.p12
new file mode 100644
index 0000000..ad2d7d3
Binary files /dev/null and b/examples/c/ssl_certs/tclient-full.p12 differ
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tclient-private-key.pem
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tclient-private-key.pem b/examples/c/ssl_certs/tclient-private-key.pem
new file mode 100644
index 0000000..e5c114d
--- /dev/null
+++ b/examples/c/ssl_certs/tclient-private-key.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQICy6ghWp45z4CAggA
+MBQGCCqGSIb3DQMHBAiVdDoo4NIghQSCBMixGm1bm/omMxsaKnIPO7zm5dyLexJ+
+yTFpmh2KV7kQqmpzCyIOdoG6K8YqFnie2XdFWm3S8faRHoMq54bDmyEWIxfQPq5f
+I1iYFbIZkbnhUvK53RActsEUMf0locS4xylU7VQK3XTAwp0TVip3Lp3ehEMEdcXL
+iUWibGsoTPKcY9MIWGXZAJXsEXoeHt6k2hHo1G4E0/Bi6mLW1LY/cxZCjHTGD6qI
+Kt54SCCDvinqVa+rixw6yX9F14EA6bhALami8e+Ccd3lqHOyYlXcBaSS1ezCg6ig
+oNK97mC+gEGy1KlkZDKWXclFoOCBXRBe4DByre6Rlq3yeI9L42bvAuSBSmf5QT5g
+73Yl8vjEAKR65awBT09dPuKu7t+Fb6vkwF8/t+uyj9IuL+42UuXhMLK3ohf+6DbU
+8/zB4y3GXI80QmWM0+Wx4n6khFhPFLHt2q0Sn6V9PG1vtHyiq50oSCoyrPQLaecp
+hefnMCFBYTcT3JUwmoVGGy0boIAwL7T4aGsMt7QhwOx5tU35tKFxyY7m4fX14AKo
+2EIy+TPQwCGkGf3Puy/Pc9VA8IAxB5+WwSrjk+NeCv88eIX7gy43k4rCr+OmD9FF
+wknr3xoP3KYhNXjdZ4Ep/1UHSK+JAtzzbNLQjDcqN+gQPg/yUX6ih0j5K3Wvh9bK
+E/DvzbpJroUZPgzR+8z5O68CfsD+OIdpHBFTKqAFmzvUuqpADpr998LdCjD+lW+V
+xZZgZa8KEblwgiH3fdGbYl46Ho1zrZisf439DbqyybAuBIQB4NSZcL/MAgVGO17k
+QDpVElWZWYrFm4CFTcvS2HvIzRmbefF5m5oJedsN7Q6WQCp+3gnwYx1xIOknd7pW
+N4AHNnqjscSj9yACj/EiBVKAKNnC5H7ZGZTsaAjMETZyjLXfI2AZ3Fviz4zFR+oz
+NkAfFB6WUpRpl7H02FzrzYT7XkkLcXd6H6g+mv2iDa9uKWk/PS2QlqnJt8/dHEHD
+JKTG331yDK5GHlKAVGF3nP5BwFGgTQMuSoeiOervMXPUwDpQ8OaYkuaRej0cZLgT
+kAF9sUjqdsoYNcXDFHALp6y5g8qYkfrxrlIbKs82zIsmB5I+dtZbUaD3a0zAUrmW
+5Xm3Pc9dVP0EXKwfHz6zqPReEw2yYLisB5IoHd4M2wa3GzHBdra1ij4QTmvd3o7e
+buGFoX8KJQAcig0zpbYkoDP2gPhIh9rY4unVPQNX1Q8/wRsiJAZZsYvZY+A+SmuZ
+bwSwk+8ZJRsFzdYYYhQeRytD5cDAIQiClcI5Yj4T9dWQV/gf0N/wIBDNTMp0jJAy
+1l7PuXTfGZodNJWZH0oqsrNoWbn/k67NildvvofIKX+h09Nxszr670Pvj0qoHd5/
+CWq30lnxoJBUgbikFOz6ZuuHi/ZiCXL+haH+v8hJKN5ptRKnyYJQHchRB/IOGRoT
+5lmWxo8a7K+yXhp0VBDHJfw3685ms0xQX8Xj4X3MEuN64zd0fB1JmhtP12ydK85J
+ABawNKlRQPw5weckwtCviXQX+vX25S/xu3xA6IuqlHyqL/1t3DICzuxeOyT2mZxD
+tKQxEgNihPvu32vn9m74qA3adEaxuWPRkPZuTeITHOkMTZolvqYX/5olBsSgYwka
+7/g=
+-----END ENCRYPTED PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tserver-certificate.p12
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tserver-certificate.p12 b/examples/c/ssl_certs/tserver-certificate.p12
new file mode 100644
index 0000000..f38b67d
Binary files /dev/null and b/examples/c/ssl_certs/tserver-certificate.p12 differ
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tserver-certificate.pem
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tserver-certificate.pem b/examples/c/ssl_certs/tserver-certificate.pem
new file mode 100644
index 0000000..86231f3
--- /dev/null
+++ b/examples/c/ssl_certs/tserver-certificate.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDKzCCAhOgAwIBAgIJAPnYOOQCJ3kDMA0GCSqGSIb3DQEBCwUAMCwxFDASBgNV
+BAMMC3Rlc3Rfc2VydmVyMRQwEgYDVQQLDAtwcm90b25fdGVzdDAeFw0xNTExMjcx
+ODEwMzlaFw0yNTExMjQxODEwMzlaMCwxFDASBgNVBAMMC3Rlc3Rfc2VydmVyMRQw
+EgYDVQQLDAtwcm90b25fdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKJNB78lgw4KtXDAvXocTLud6mbn6zgfB6ETIF+kcrukOH9DnPxjLBBM4Lig
+sp1+kmeudFK5/X8riDrvIW52b/rlEBLgLB+oDtI74m6OTbBs9L+FUFYOuxApetQF
+qoJy2vf9pWfy4uku24vCpeo7eVLi6ypu4lXE3LR+Km3FruHI1NKonHBMhwXSOWqF
+pYM6/4IZJ4fbV0+eU0Jrx+05s6XHg5vone2BVJKxeSIBje+zWnNnh8+qG0Z70Jgp
+aMetME5KGnLNgD1okpH0vb3lwjvuqkkx4WswGVZGbLLkSqqBpXPyM9fCFVy5aKSL
+DBq7IABQtO67O2nBzK3OyigHrUUCAwEAAaNQME4wHQYDVR0OBBYEFGV1PY0FCFbJ
+gpcDVKI6JGiRTt3kMB8GA1UdIwQYMBaAFGV1PY0FCFbJgpcDVKI6JGiRTt3kMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIx1TOTGWnnbpan4bse7wuvH
+GYSNDJhoTVS+X1TC63xukJD1JBAsCNTqg/ZV6lN3XEl7vvOXfGoCiyXM6a9XOKUo
+gSDtMrIr+wTh6Ss1yRO8QcCJmxH5JDXNu1ojtwsjFW/vneI4IL9kwpDsSlMQEX/E
+EkkQwtAx/Cvfe7pecZL4qSeykJOUMTts9H8fCAZqEiRZBA3ugJxqF8jwLP3DoFVQ
+6QZzKDY6CSPqfMnVb5i0MAIYVDpau+e3N9dgQpZD22F/zbua0OVbfAPdiRMnYxML
+FT4sxLnh+5YVqwpVWbEKp4onHe2Fq6YIvAxUYAJ3SBA2C8O2RAVKWxf1jko3jYI=
+-----END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tserver-full.p12
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tserver-full.p12 b/examples/c/ssl_certs/tserver-full.p12
new file mode 100644
index 0000000..d4a0e40
Binary files /dev/null and b/examples/c/ssl_certs/tserver-full.p12 differ
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/examples/c/ssl_certs/tserver-private-key.pem
----------------------------------------------------------------------
diff --git a/examples/c/ssl_certs/tserver-private-key.pem b/examples/c/ssl_certs/tserver-private-key.pem
new file mode 100644
index 0000000..91dcf0e
--- /dev/null
+++ b/examples/c/ssl_certs/tserver-private-key.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI1cT0c2J3GcQCAggA
+MBQGCCqGSIb3DQMHBAi1hxSX2LJ+EgSCBMheHJ0iXr5A36Natjk/LcAEeKUMT9s+
+sMzoQceCWe8qMlQluWksr9iDdZ4JRIE8cpK8dbmx4dLY/SShUzdlhJHCSa4zZBHq
+8cZ/jGUF/RF1rqdgjK589eUq+uOl3/gXKzG/SxBqayy6PSn12kX3qnvmlkXCmtwU
+lg+iBm5wRcJ0MyVHaJkyA8sW8gr186C/VAau6Yu0crQXN7NRo9snrd4ewuYMIEhZ
+hgaG9XsYQWB1bPhAaKj80CZGxsQbJyTwcbKKkB3IY4WXx8mmhuiNl+vKT3HBJ9Ju
+YB6tgIjs8CJ4X2P4aU3yNJwG1QldgHSqmFGQ19bcZAw3s3kzwjdzRf4H2V16XOBd
+zQ5AEs/ffVMzMIAfkb1gYwgunZ2CVwwDJ2mi1RcgkX+Og2aFQc+fxXcVOnDcGLxV
+6fuCuZ2lsXfoiIyRh9kj3L75N12GtVUvgBdnMuOc1wPw6XnGQtDwt0acJpdexLMG
+k0j57r/gcgzTcmF3qNM+y9L/HLssgrJkvVJw2Np5gmtIyfDocsDUWUbClS4dTpYf
+oTngUTU+vWtHBuaUnb+f5/WJaRS/S7mmR8usbVG3i9WnEr/vlPJpbJFSjW2S6u/H
+7cFxKUmmBZsSuEv/EKt9a+Sh62kprOChm4myqfCI1/gvNKfUZC6m0Vp8zf+2LgAq
+2RgbMuqysMjWUtV4kDRZT7oCYckUDwsCHdbLES3nmVrtBk2ShMKHBpDp8/GoRuiV
+jdV7/EjKM/M1kXtFYYe3z7Mxv++lKYIJ7bNwVrQ8nrhce/VwHw6D5emWXNCJXhKZ
+FW7EM2ZOZ9eaKOlCsIi8sbjV6Yie9IY6HJKKmi3CpO0Tv5kLBdHkru8vGCSFm3O1
+n7wz7Ys5FBSlZ19X0NwQSCQX1Q4w+tido6i1SCRX0qJEdTNGuGwVXMHCf4/1zyHV
+hj8vnxh8fzo79LFrwlTTgwLg1Mr8sEUFFDJ/raJ1AhFXi8n24trtNR8EHxRW8wtD
+CLCKaqkEqfBiFXK/Yq3RrefCayPHiD+DaNsI8BwefMGpED3vD8YYCjAzXNPh/CSF
+sc1i1jWMzbJhzOoFSPNXhlfusbUFMFQ/6olatmH47SY6HBBOL3DDP5uQ0jw8P454
+QBjlMOpEZmZxO6TcEtJwu0vzgog4rQ5g3NWy6SIpjWehNwTynLt7yM3R5WTI6cZs
+0GTv/rqo2/SUoNsFmnGIUwj/DrBe4XOAq1nS2ZlEctxKhBsKH0hMFp6D1rXOzrgl
+bwcq+oistoB0TLcThShyNgSqzW1znQ1n5SVUk9b5rRhSttJxn3yOMewH0i3v8bPo
+HOhP5kaGjblPsCYyhlL/SNVF0OXEGTwLNey7FQdWFOwVwTRRXe7k+uGZ2d5hg+Jn
+It/trDZ1RDYbVmB7/Qy73c16J4mvhOUJ2de5ZciFBjkidbiiUKLj9xnjK9k9Sauo
+MKhNnDMAEU5VDQM3xNe5BRdX8dFLwfF5H64sU3nROF83aUnDgvfFEowYPnCuPYfm
+m4aQHfoBSg4j3v1OeOwktcl+Q2TjxPHfWhbWeRBfxOTqQ/suYhnQChuFSK/qyo9K
+ccgotqghhunRsWMoZT25H7AZM6yKb1sMz/0oyMRIKeGqoYh+ULM5XLY0xNYd4/xU
+WtQ=
+-----END ENCRYPTED PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/proton-c/src/ssl/openssl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c
index 3929f88..f8479f0 100644
--- a/proton-c/src/ssl/openssl.c
+++ b/proton-c/src/ssl/openssl.c
@@ -57,11 +57,10 @@
* This file contains an OpenSSL-based implemention of the SSL/TLS API.
*/
-static int ssl_initialized;
-static int ssl_ex_data_index;
-
typedef struct pn_ssl_session_t pn_ssl_session_t;
+static int ssl_ex_data_index;
+
struct pn_ssl_domain_t {
SSL_CTX *ctx;
@@ -119,14 +118,14 @@ struct pni_ssl_t {
static inline pn_transport_t *get_transport_internal(pn_ssl_t *ssl)
{
- // The external pn_sasl_t is really a pointer to the internal pni_transport_t
- return ((pn_transport_t *)ssl);
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return ((pn_transport_t *)ssl);
}
static inline pni_ssl_t *get_ssl_internal(pn_ssl_t *ssl)
{
- // The external pn_sasl_t is really a pointer to the internal pni_transport_t
- return ssl ? ((pn_transport_t *)ssl)->ssl : NULL;
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return ssl ? ((pn_transport_t *)ssl)->ssl : NULL;
}
// define two sets of allowable ciphers: those that require authentication, and those
@@ -265,8 +264,8 @@ static bool match_dns_pattern( const char *hostname,
int suffix_len = strlen(suffix);
if (prefix_len && pn_strncasecmp( prefix, slabel, prefix_len )) return false;
if (suffix_len && pn_strncasecmp( suffix,
- slabel + (strlen(slabel) - suffix_len),
- suffix_len )) return false;
+ slabel + (strlen(slabel) - suffix_len),
+ suffix_len )) return false;
}
}
@@ -348,7 +347,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
if (!matched) {
ssl_log(transport, "Error: no name matching %s found in peer cert - rejecting handshake.",
- ssl->peer_hostname);
+ ssl->peer_hostname);
preverify_ok = 0;
#ifdef X509_V_ERR_APPLICATION_VERIFICATION
X509_STORE_CTX_set_error( ctx, X509_V_ERR_APPLICATION_VERIFICATION );
@@ -477,18 +476,14 @@ bool pn_ssl_present(void)
return true;
}
+static bool ensure_initialized(void);
+
pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
{
- if (!ssl_initialized) {
- ssl_initialized = 1;
- SSL_library_init();
- SSL_load_error_strings();
- OpenSSL_add_all_algorithms();
- ssl_ex_data_index = SSL_get_ex_new_index( 0, (void *) "org.apache.qpid.proton.ssl",
- NULL, NULL, NULL);
- ssn_init();
+ if (!ensure_initialized()) {
+ ssl_log_error("Unable to initialize OpenSSL library");
+ return NULL;
}
-
pn_ssl_domain_t *domain = (pn_ssl_domain_t *) calloc(1, sizeof(pn_ssl_domain_t));
if (!domain) return NULL;
@@ -499,7 +494,7 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
// known vulnerable ones. This should allow us to use the latest version
// of the TLS standard that the installed library supports.
switch(mode) {
- case PN_SSL_MODE_CLIENT:
+ case PN_SSL_MODE_CLIENT:
domain->ctx = SSL_CTX_new(SSLv23_client_method()); // and TLSv1+
SSL_CTX_set_session_cache_mode(domain->ctx, SSL_SESS_CACHE_CLIENT);
if (!domain->ctx) {
@@ -509,7 +504,7 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
}
break;
- case PN_SSL_MODE_SERVER:
+ case PN_SSL_MODE_SERVER:
domain->ctx = SSL_CTX_new(SSLv23_server_method()); // and TLSv1+
if (!domain->ctx) {
ssl_log_error("Unable to initialize OpenSSL context.");
@@ -518,7 +513,7 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
}
break;
- default:
+ default:
pn_transport_logf(NULL, "Invalid value for pn_ssl_mode_t: %d", mode);
free(domain);
return NULL;
@@ -530,7 +525,7 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
SSL_CTX_set_options(domain->ctx, SSL_OP_NO_COMPRESSION);
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000
- domain->default_seclevel = SSL_CTX_get_security_level(domain->ctx);
+ domain->default_seclevel = SSL_CTX_get_security_level(domain->ctx);
#endif
// by default, allow anonymous ciphers so certificates are not required 'out of the box'
@@ -570,9 +565,9 @@ void pn_ssl_domain_free( pn_ssl_domain_t *domain )
int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
- const char *certificate_file,
- const char *private_key_file,
- const char *password)
+ const char *certificate_file,
+ const char *private_key_file,
+ const char *password)
{
if (!domain || !domain->ctx) return -1;
@@ -594,7 +589,7 @@ int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
if (SSL_CTX_check_private_key(domain->ctx) != 1) {
ssl_log_error("The key file %s is not consistent with the certificate %s",
- private_key_file, certificate_file);
+ private_key_file, certificate_file);
return -5;
}
@@ -604,8 +599,8 @@ int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
// cipher was negotiated. TLSv1 will reject such a request. Hack: once a cert is
// configured, allow only authenticated ciphers.
if (!domain->ciphers && !SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_AUTHENTICATE )) {
- ssl_log_error("Failed to set cipher list to %s", CIPHERS_AUTHENTICATE);
- return -6;
+ ssl_log_error("Failed to set cipher list to %s", CIPHERS_AUTHENTICATE);
+ return -6;
}
return 0;
@@ -664,8 +659,8 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
if (!domain) return -1;
switch (mode) {
- case PN_SSL_VERIFY_PEER:
- case PN_SSL_VERIFY_PEER_NAME:
+ case PN_SSL_VERIFY_PEER:
+ case PN_SSL_VERIFY_PEER_NAME:
#if OPENSSL_VERSION_NUMBER >= 0x10100000
SSL_CTX_set_security_level(domain->ctx, domain->default_seclevel);
@@ -673,7 +668,7 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
if (!domain->has_ca_db) {
pn_transport_logf(NULL, "Error: cannot verify peer without a trusted CA configured.\n"
- " Use pn_ssl_domain_set_trusted_ca_db()");
+ " Use pn_ssl_domain_set_trusted_ca_db()");
return -1;
}
@@ -686,7 +681,7 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
}
if (!domain->has_certificate) {
pn_transport_logf(NULL, "Error: Server cannot verify peer without configuring a certificate.\n"
- " Use pn_ssl_domain_set_credentials()");
+ " Use pn_ssl_domain_set_credentials()");
}
if (domain->trusted_CAs) free(domain->trusted_CAs);
@@ -708,7 +703,7 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
#endif
break;
- case PN_SSL_ANONYMOUS_PEER: // hippie free love mode... :)
+ case PN_SSL_ANONYMOUS_PEER: // hippie free love mode... :)
#if OPENSSL_VERSION_NUMBER >= 0x10100000
// Must use lowest OpenSSL security level to enable anonymous ciphers.
SSL_CTX_set_security_level(domain->ctx, 0);
@@ -716,7 +711,7 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
SSL_CTX_set_verify( domain->ctx, SSL_VERIFY_NONE, NULL );
break;
- default:
+ default:
pn_transport_logf(NULL, "Invalid peer authentication mode given." );
return -1;
}
@@ -726,35 +721,35 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
}
const pn_io_layer_t ssl_layer = {
- process_input_ssl,
- process_output_ssl,
- handle_error_ssl,
- NULL,
- buffered_output
+ process_input_ssl,
+ process_output_ssl,
+ handle_error_ssl,
+ NULL,
+ buffered_output
};
const pn_io_layer_t ssl_input_closed_layer = {
- process_input_done,
- process_output_ssl,
- handle_error_ssl,
- NULL,
- buffered_output
+ process_input_done,
+ process_output_ssl,
+ handle_error_ssl,
+ NULL,
+ buffered_output
};
const pn_io_layer_t ssl_output_closed_layer = {
- process_input_ssl,
- process_output_done,
- handle_error_ssl,
- NULL,
- buffered_output
+ process_input_ssl,
+ process_output_done,
+ handle_error_ssl,
+ NULL,
+ buffered_output
};
const pn_io_layer_t ssl_closed_layer = {
- process_input_done,
- process_output_done,
- handle_error_ssl,
- NULL,
- buffered_output
+ process_input_done,
+ process_output_done,
+ handle_error_ssl,
+ NULL,
+ buffered_output
};
int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id)
@@ -886,9 +881,9 @@ pn_ssl_t *pn_ssl(pn_transport_t *transport)
static int keyfile_pw_cb(char *buf, int size, int rwflag, void *userdata)
{
- strncpy(buf, (char *)userdata, size); // @todo: un-obfuscate me!!!
- buf[size - 1] = '\0';
- return(strlen(buf));
+ strncpy(buf, (char *)userdata, size); // @todo: un-obfuscate me!!!
+ buf[size - 1] = '\0';
+ return(strlen(buf));
}
@@ -958,13 +953,13 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
if (!BIO_should_retry(ssl->bio_ssl)) {
int reason = SSL_get_error( ssl->ssl, read );
switch (reason) {
- case SSL_ERROR_ZERO_RETURN:
+ case SSL_ERROR_ZERO_RETURN:
// SSL closed cleanly
ssl_log(transport, "SSL connection has closed");
start_ssl_shutdown(transport); // KAG: not sure - this may not be necessary
ssl->ssl_closed = true;
break;
- default:
+ default:
// unexpected error
return (ssize_t)ssl_failed(transport);
}
@@ -994,7 +989,7 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
ssl_log( transport, "Application consumed %d bytes from peer", (int) consumed );
} else if (consumed < 0) {
ssl_log(transport, "Application layer closed its input, error=%d (discarding %d bytes)",
- (int) consumed, (int)ssl->in_count);
+ (int) consumed, (int)ssl->in_count);
ssl->in_count = 0; // discard any pending input
ssl->app_input_closed = consumed;
if (ssl->app_output_closed && ssl->out_count == 0) {
@@ -1086,7 +1081,7 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
} else {
if (app_bytes < 0) {
ssl_log(transport, "Application layer closed its output, error=%d (%d bytes pending send)",
- (int) app_bytes, (int) ssl->out_count);
+ (int) app_bytes, (int) ssl->out_count);
ssl->app_output_closed = app_bytes;
}
}
@@ -1107,14 +1102,14 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
if (!BIO_should_retry(ssl->bio_ssl)) {
int reason = SSL_get_error( ssl->ssl, wrote );
switch (reason) {
- case SSL_ERROR_ZERO_RETURN:
+ case SSL_ERROR_ZERO_RETURN:
// SSL closed cleanly
ssl_log(transport, "SSL connection has closed");
start_ssl_shutdown(transport); // KAG: not sure - this may not be necessary
ssl->out_count = 0; // can no longer write to socket, so erase app output data
ssl->ssl_closed = true;
break;
- default:
+ default:
// unexpected error
return (ssize_t)ssl_failed(transport);
}
@@ -1236,7 +1231,7 @@ static void release_ssl_socket(pni_ssl_t *ssl)
{
if (ssl->bio_ssl) BIO_free(ssl->bio_ssl);
if (ssl->ssl) {
- SSL_free(ssl->ssl); // will free bio_ssl_io
+ SSL_free(ssl->ssl); // will free bio_ssl_io
} else {
if (ssl->bio_ssl_io) BIO_free(ssl->bio_ssl_io);
}
@@ -1254,9 +1249,9 @@ pn_ssl_resume_status_t pn_ssl_resume_status(pn_ssl_t *ssl0)
pni_ssl_t *ssl = get_ssl_internal(ssl0);
if (!ssl || !ssl->ssl) return PN_SSL_RESUME_UNKNOWN;
switch (SSL_session_reused( ssl->ssl )) {
- case 0: return PN_SSL_RESUME_NEW;
- case 1: return PN_SSL_RESUME_REUSED;
- default: break;
+ case 0: return PN_SSL_RESUME_NEW;
+ case 1: return PN_SSL_RESUME_REUSED;
+ default: break;
}
return PN_SSL_RESUME_UNKNOWN;
}
@@ -1332,124 +1327,124 @@ const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl0)
int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl0, char *fingerprint, size_t fingerprint_length, pn_ssl_hash_alg hash_alg)
{
- const char *digest_name = NULL;
- size_t min_required_length;
-
- // old versions of python expect fingerprint to contain a valid string on
- // return from this function
- fingerprint[0] = 0;
-
- // Assign the correct digest_name value based on the enum values.
- switch (hash_alg) {
- case PN_SSL_SHA1 :
- min_required_length = 41; // 40 hex characters + 1 '\0' character
- digest_name = "sha1";
- break;
- case PN_SSL_SHA256 :
- min_required_length = 65; // 64 hex characters + 1 '\0' character
- digest_name = "sha256";
- break;
- case PN_SSL_SHA512 :
- min_required_length = 129; // 128 hex characters + 1 '\0' character
- digest_name = "sha512";
- break;
- case PN_SSL_MD5 :
- min_required_length = 33; // 32 hex characters + 1 '\0' character
- digest_name = "md5";
- break;
- default:
- ssl_log_error("Unknown or unhandled hash algorithm %i \n", hash_alg);
- return PN_ERR;
-
- }
+ const char *digest_name = NULL;
+ size_t min_required_length;
+
+ // old versions of python expect fingerprint to contain a valid string on
+ // return from this function
+ fingerprint[0] = 0;
+
+ // Assign the correct digest_name value based on the enum values.
+ switch (hash_alg) {
+ case PN_SSL_SHA1 :
+ min_required_length = 41; // 40 hex characters + 1 '\0' character
+ digest_name = "sha1";
+ break;
+ case PN_SSL_SHA256 :
+ min_required_length = 65; // 64 hex characters + 1 '\0' character
+ digest_name = "sha256";
+ break;
+ case PN_SSL_SHA512 :
+ min_required_length = 129; // 128 hex characters + 1 '\0' character
+ digest_name = "sha512";
+ break;
+ case PN_SSL_MD5 :
+ min_required_length = 33; // 32 hex characters + 1 '\0' character
+ digest_name = "md5";
+ break;
+ default:
+ ssl_log_error("Unknown or unhandled hash algorithm %i \n", hash_alg);
+ return PN_ERR;
- if(fingerprint_length < min_required_length) {
- ssl_log_error("Insufficient fingerprint_length %i. fingerprint_length must be %i or above for %s digest\n",
- fingerprint_length, min_required_length, digest_name);
- return PN_ERR;
- }
+ }
- const EVP_MD *digest = EVP_get_digestbyname(digest_name);
+ if(fingerprint_length < min_required_length) {
+ ssl_log_error("Insufficient fingerprint_length %i. fingerprint_length must be %i or above for %s digest\n",
+ fingerprint_length, min_required_length, digest_name);
+ return PN_ERR;
+ }
- pni_ssl_t *ssl = get_ssl_internal(ssl0);
- X509 *cert = get_peer_certificate(ssl);
+ const EVP_MD *digest = EVP_get_digestbyname(digest_name);
- if(cert) {
- unsigned int len;
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
+ X509 *cert = get_peer_certificate(ssl);
- unsigned char bytes[64]; // sha512 uses 64 octets, we will use that as the maximum.
+ if(cert) {
+ unsigned int len;
- if (X509_digest(cert, digest, bytes, &len) != 1) {
- ssl_log_error("Failed to extract X509 digest\n");
- return PN_ERR;
- }
+ unsigned char bytes[64]; // sha512 uses 64 octets, we will use that as the maximum.
- char *cursor = fingerprint;
+ if (X509_digest(cert, digest, bytes, &len) != 1) {
+ ssl_log_error("Failed to extract X509 digest\n");
+ return PN_ERR;
+ }
- for (size_t i=0; i<len ; i++) {
- cursor += pni_snprintf((char *)cursor, fingerprint_length, "%02x", bytes[i]);
- fingerprint_length = fingerprint_length - 2;
- }
+ char *cursor = fingerprint;
- return PN_OK;
- }
- else {
- ssl_log_error("No certificate is available yet \n");
- return PN_ERR;
+ for (size_t i=0; i<len ; i++) {
+ cursor += pni_snprintf((char *)cursor, fingerprint_length, "%02x", bytes[i]);
+ fingerprint_length = fingerprint_length - 2;
}
- return 0;
+ return PN_OK;
+ }
+ else {
+ ssl_log_error("No certificate is available yet \n");
+ return PN_ERR;
+ }
+
+ return 0;
}
const char* pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subject_subfield field)
{
- int openssl_field = 0;
+ int openssl_field = 0;
- // Assign openssl internal representations of field values to openssl_field
- switch (field) {
- case PN_SSL_CERT_SUBJECT_COUNTRY_NAME :
- openssl_field = NID_countryName;
- break;
- case PN_SSL_CERT_SUBJECT_STATE_OR_PROVINCE :
- openssl_field = NID_stateOrProvinceName;
- break;
- case PN_SSL_CERT_SUBJECT_CITY_OR_LOCALITY :
- openssl_field = NID_localityName;
- break;
- case PN_SSL_CERT_SUBJECT_ORGANIZATION_NAME :
- openssl_field = NID_organizationName;
- break;
- case PN_SSL_CERT_SUBJECT_ORGANIZATION_UNIT :
- openssl_field = NID_organizationalUnitName;
- break;
- case PN_SSL_CERT_SUBJECT_COMMON_NAME :
- openssl_field = NID_commonName;
- break;
- default:
- ssl_log_error("Unknown or unhandled certificate subject subfield %i \n", field);
- return NULL;
- }
+ // Assign openssl internal representations of field values to openssl_field
+ switch (field) {
+ case PN_SSL_CERT_SUBJECT_COUNTRY_NAME :
+ openssl_field = NID_countryName;
+ break;
+ case PN_SSL_CERT_SUBJECT_STATE_OR_PROVINCE :
+ openssl_field = NID_stateOrProvinceName;
+ break;
+ case PN_SSL_CERT_SUBJECT_CITY_OR_LOCALITY :
+ openssl_field = NID_localityName;
+ break;
+ case PN_SSL_CERT_SUBJECT_ORGANIZATION_NAME :
+ openssl_field = NID_organizationName;
+ break;
+ case PN_SSL_CERT_SUBJECT_ORGANIZATION_UNIT :
+ openssl_field = NID_organizationalUnitName;
+ break;
+ case PN_SSL_CERT_SUBJECT_COMMON_NAME :
+ openssl_field = NID_commonName;
+ break;
+ default:
+ ssl_log_error("Unknown or unhandled certificate subject subfield %i \n", field);
+ return NULL;
+ }
- pni_ssl_t *ssl = get_ssl_internal(ssl0);
- X509 *cert = get_peer_certificate(ssl);
- if (!cert) return NULL;
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
+ X509 *cert = get_peer_certificate(ssl);
+ if (!cert) return NULL;
- X509_NAME *subject_name = X509_get_subject_name(cert);
+ X509_NAME *subject_name = X509_get_subject_name(cert);
- // TODO (gmurthy) - A server side cert subject field can have more than one common name like this - Subject: CN=www.domain1.com, CN=www.domain2.com, see https://bugzilla.mozilla.org/show_bug.cgi?id=380656
- // For now, we will only return the first common name if there is more than one common name in the cert
- int index = X509_NAME_get_index_by_NID(subject_name, openssl_field, -1);
+ // TODO (gmurthy) - A server side cert subject field can have more than one common name like this - Subject: CN=www.domain1.com, CN=www.domain2.com, see https://bugzilla.mozilla.org/show_bug.cgi?id=380656
+ // For now, we will only return the first common name if there is more than one common name in the cert
+ int index = X509_NAME_get_index_by_NID(subject_name, openssl_field, -1);
- if (index > -1) {
- X509_NAME_ENTRY *ne = X509_NAME_get_entry(subject_name, index);
- if(ne) {
- ASN1_STRING *name_asn1 = X509_NAME_ENTRY_get_data(ne);
- return (char *) name_asn1->data;
- }
+ if (index > -1) {
+ X509_NAME_ENTRY *ne = X509_NAME_get_entry(subject_name, index);
+ if(ne) {
+ ASN1_STRING *name_asn1 = X509_NAME_ENTRY_get_data(ne);
+ return (char *) name_asn1->data;
}
+ }
- return NULL;
+ return NULL;
}
static ssize_t process_input_done(pn_transport_t *transport, unsigned int layer, const char *input_data, size_t len)
@@ -1474,3 +1469,88 @@ static size_t buffered_output(pn_transport_t *transport)
}
return count;
}
+
+
+/* Thread-safe locking and initialization for POSIX and Windows */
+
+static bool init_ok = false;
+
+#ifdef _WIN32
+
+typedef CRITICAL_SECTION pni_mutex_t;
+static inline void pni_mutex_init(pni_mutex_t *m) { InitializeCriticalSection(m); }
+static inline void pni_mutex_lock(pni_mutex_t *m) { EnterCriticalSection(m); }
+static inline void pni_mutex_unlock(pni_mutex_t *m) { LeaveCriticalSection(m); }
+static inline unsigned long id_callback(void) { return (unsigned long)GetCurrentThreadId(); }
+INIT_ONCE initialize_once = INIT_ONCE_STATIC_INIT;
+static inline bool ensure_initialized(void) {
+ void* dummy;
+ InitOnceExecuteOnce(&initialize_once, &initialize, NULL, &dummy);
+ return init_ok;
+}
+
+#else /* POSIX */
+
+#include <pthread.h>
+
+static void initialize(void);
+
+typedef pthread_mutex_t pni_mutex_t;
+static inline int pni_mutex_init(pni_mutex_t *m) { return pthread_mutex_init(m, NULL); }
+static inline int pni_mutex_lock(pni_mutex_t *m) { return pthread_mutex_lock(m); }
+static inline int pni_mutex_unlock(pni_mutex_t *m) { return pthread_mutex_unlock(m); }
+static inline unsigned long id_callback(void) { return (unsigned long)pthread_self(); }
+static pthread_once_t initialize_once = PTHREAD_ONCE_INIT;
+static inline bool ensure_initialized(void) {
+ pthread_once(&initialize_once, &initialize);
+ return init_ok;
+}
+
+#endif
+
+static pni_mutex_t *locks = NULL; /* Lock array for openssl */
+
+/* Callback function for openssl locking */
+static void locking_callback(int mode, int n, const char *file, int line) {
+ if(mode & CRYPTO_LOCK)
+ pni_mutex_lock(&locks[n]);
+ else
+ pni_mutex_unlock(&locks[n]);
+}
+
+static void initialize(void) {
+ int i;
+ SSL_library_init();
+ SSL_load_error_strings();
+ OpenSSL_add_all_algorithms();
+ ssl_ex_data_index = SSL_get_ex_new_index( 0, (void *) "org.apache.qpid.proton.ssl",
+ NULL, NULL, NULL);
+ ssn_init();
+ locks = (pni_mutex_t*)malloc(CRYPTO_num_locks() * sizeof(pni_mutex_t));
+ if (!locks) return;
+ for(i = 0; i < CRYPTO_num_locks(); i++)
+ pni_mutex_init(&locks[i]);
+ CRYPTO_set_id_callback(&id_callback);
+ CRYPTO_set_locking_callback(&locking_callback);
+ /* In recent versions of openssl, the set_callback functions are no-op macros,
+ so we need to take steps to stop the compiler complaining about unused functions. */
+ (void)&id_callback;
+ (void)&locking_callback;
+ init_ok = true;
+}
+
+/* TODO aconway 2017-10-16: There is no opportunity to clean up the locks as proton has no
+ final shut-down call. If it did, we should call this: */
+/*
+static void shutdown(void) {
+ CRYPTO_set_id_callback(NULL);
+ CRYPTO_set_locking_callback(NULL);
+ if(locks) {
+ int i;
+ for(i = 0; i < CRYPTO_num_locks(); i++)
+ pni_mutex_destroy(&locks[i]);
+ free(locks);
+ locks = NULL;
+ }
+}
+*/
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/434a2e77/proton-c/src/tests/proactor.c
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/proactor.c b/proton-c/src/tests/proactor.c
index 5f84bfe..a0b2a15 100644
--- a/proton-c/src/tests/proactor.c
+++ b/proton-c/src/tests/proactor.c
@@ -686,7 +686,6 @@ static void test_release_free(test_t *t) {
# define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.p12")
# define SET_CREDENTIALS(DOMAIN, NAME) \
pn_ssl_domain_set_credentials(DOMAIN, SSL_FILE(NAME "-full.p12"), "", SSL_PW)
-
#else
# define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.pem")
# define SET_CREDENTIALS(DOMAIN, NAME) \
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org