Add --management-external-key support, compatible with the OpenSSL
implementation. Needs the flexibility of ssl_set_own_cert_alt(), which
is new in PolarSSL-1.2.
Signed-off-by: Joachim Schipper <joachim.schipper@fox-it.com>
Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1379587649-25506-3-git-send-email-steffan.karger@fox-it.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/7886
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -121,6 +121,10 @@ tls_ctx_free(struct tls_root_ctx *ctx) |
121 | 121 |
free(ctx->priv_key_pkcs11); |
122 | 122 |
} |
123 | 123 |
#endif |
124 |
+#if defined(MANAGMENT_EXTERNAL_KEY) |
|
125 |
+ if (ctx->external_key != NULL) |
|
126 |
+ free(ctx->external_key); |
|
127 |
+#endif |
|
124 | 128 |
|
125 | 129 |
if (ctx->allowed_ciphers) |
126 | 130 |
free(ctx->allowed_ciphers); |
... | ... |
@@ -309,14 +313,95 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, |
309 | 309 |
|
310 | 310 |
#ifdef MANAGMENT_EXTERNAL_KEY |
311 | 311 |
|
312 |
+ |
|
313 |
+struct external_context { |
|
314 |
+ size_t signature_length; |
|
315 |
+}; |
|
316 |
+ |
|
317 |
+int |
|
312 | 318 |
tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, |
313 |
- const char *cert_file, const char *cert_file_inline |
|
314 |
- ) |
|
319 |
+ const char *cert_file, const char *cert_file_inline) |
|
315 | 320 |
{ |
316 |
- msg(M_FATAL, "Use of management external keys not yet supported for PolarSSL."); |
|
317 |
- return false; |
|
321 |
+ ASSERT(NULL != ctx); |
|
322 |
+ |
|
323 |
+ tls_ctx_load_cert_file(ctx, cert_file, cert_file_inline); |
|
324 |
+ |
|
325 |
+ if (ctx->crt_chain == NULL) |
|
326 |
+ return 0; |
|
327 |
+ |
|
328 |
+ /* Most of the initialization happens in key_state_ssl_init() */ |
|
329 |
+ ALLOC_OBJ_CLEAR (ctx->external_key, struct external_context); |
|
330 |
+ ctx->external_key->signature_length = ctx->crt_chain->rsa.len; |
|
331 |
+ |
|
332 |
+ return 1; |
|
318 | 333 |
} |
319 | 334 |
|
335 |
+static inline int external_pkcs1_sign( void *ctx_voidptr, |
|
336 |
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, |
|
337 |
+ int hash_id, unsigned int hashlen, const unsigned char *hash, |
|
338 |
+ unsigned char *sig ) |
|
339 |
+{ |
|
340 |
+ struct external_context * const ctx = ctx_voidptr; |
|
341 |
+ char *in_b64 = NULL; |
|
342 |
+ char *out_b64 = NULL; |
|
343 |
+ int rv; |
|
344 |
+ |
|
345 |
+ ASSERT(NULL != ctx); |
|
346 |
+ |
|
347 |
+ if (RSA_PRIVATE != mode) |
|
348 |
+ { |
|
349 |
+ rv = POLARSSL_ERR_RSA_BAD_INPUT_DATA; |
|
350 |
+ goto done; |
|
351 |
+ } |
|
352 |
+ |
|
353 |
+ /* |
|
354 |
+ * Normally (i.e. rsa_pkcs1_sign()), the padding is set in the context, and |
|
355 |
+ * we have padding-specific code to handle various hash_id's here. Since the |
|
356 |
+ * management client will RSA-sign the bytes we present without further |
|
357 |
+ * processing, we only support SIG_RSA_RAW (PolarSSL's equivalent of |
|
358 |
+ * OpenSSL's NID_md5_sha1). |
|
359 |
+ */ |
|
360 |
+ ASSERT(hash_id == SIG_RSA_RAW); |
|
361 |
+ /* convert 'from' to base64 */ |
|
362 |
+ if (openvpn_base64_encode (hash, hashlen, &in_b64) <= 0) |
|
363 |
+ { |
|
364 |
+ rv = POLARSSL_ERR_RSA_BAD_INPUT_DATA; |
|
365 |
+ goto done; |
|
366 |
+ } |
|
367 |
+ |
|
368 |
+ /* call MI for signature */ |
|
369 |
+ if (management) |
|
370 |
+ out_b64 = management_query_rsa_sig (management, in_b64); |
|
371 |
+ if (!out_b64) |
|
372 |
+ { |
|
373 |
+ rv = POLARSSL_ERR_RSA_PRIVATE_FAILED; |
|
374 |
+ goto done; |
|
375 |
+ } |
|
376 |
+ |
|
377 |
+ /* decode base64 signature to binary and verify length */ |
|
378 |
+ if ( openvpn_base64_decode (out_b64, sig, ctx->signature_length) != |
|
379 |
+ ctx->signature_length ) |
|
380 |
+ { |
|
381 |
+ rv = POLARSSL_ERR_RSA_PRIVATE_FAILED; |
|
382 |
+ goto done; |
|
383 |
+ } |
|
384 |
+ |
|
385 |
+ rv = 0; |
|
386 |
+ |
|
387 |
+ done: |
|
388 |
+ if (in_b64) |
|
389 |
+ free (in_b64); |
|
390 |
+ if (out_b64) |
|
391 |
+ free (out_b64); |
|
392 |
+ return rv; |
|
393 |
+} |
|
394 |
+ |
|
395 |
+static inline size_t external_key_len(void *vctx) |
|
396 |
+{ |
|
397 |
+ struct external_context * const ctx = vctx; |
|
398 |
+ |
|
399 |
+ return ctx->signature_length; |
|
400 |
+} |
|
320 | 401 |
#endif |
321 | 402 |
|
322 | 403 |
void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, |
... | ... |
@@ -530,6 +615,13 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl, |
530 | 530 |
ssl_pkcs11_key_len ); |
531 | 531 |
else |
532 | 532 |
#endif |
533 |
+#if defined(MANAGMENT_EXTERNAL_KEY) |
|
534 |
+ if (ssl_ctx->external_key != NULL) |
|
535 |
+ ssl_set_own_cert_alt( ks_ssl->ctx, ssl_ctx->crt_chain, |
|
536 |
+ ssl_ctx->external_key, NULL, external_pkcs1_sign, |
|
537 |
+ external_key_len ); |
|
538 |
+ else |
|
539 |
+#endif |
|
533 | 540 |
ssl_set_own_cert( ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key ); |
534 | 541 |
|
535 | 542 |
/* Initialise SSL verification */ |
... | ... |
@@ -30,6 +30,8 @@ |
30 | 30 |
#ifndef SSL_POLARSSL_H_ |
31 | 31 |
#define SSL_POLARSSL_H_ |
32 | 32 |
|
33 |
+#include "syshead.h" |
|
34 |
+ |
|
33 | 35 |
#include <polarssl/ssl.h> |
34 | 36 |
|
35 | 37 |
#if defined(ENABLE_PKCS11) |
... | ... |
@@ -68,6 +70,9 @@ struct tls_root_ctx { |
68 | 68 |
#if defined(ENABLE_PKCS11) |
69 | 69 |
pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */ |
70 | 70 |
#endif |
71 |
+#ifdef MANAGMENT_EXTERNAL_KEY |
|
72 |
+ struct external_context *external_key; /**< Management external key */ |
|
73 |
+#endif |
|
71 | 74 |
int * allowed_ciphers; /**< List of allowed ciphers for this connection */ |
72 | 75 |
}; |
73 | 76 |
|
... | ... |
@@ -539,7 +539,7 @@ socket_defined (const socket_descriptor_t sd) |
539 | 539 |
/* |
540 | 540 |
* Enable external private key |
541 | 541 |
*/ |
542 |
-#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_SSL) && !defined(ENABLE_CRYPTO_POLARSSL) |
|
542 |
+#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_SSL) |
|
543 | 543 |
#define MANAGMENT_EXTERNAL_KEY |
544 | 544 |
#endif |
545 | 545 |
|