This prepares for reusing this code from the mbedtls pkcs11 implementation.
The change itself should not have any functional impact.
Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1536916459-25900-2-git-send-email-steffan.karger@fox-it.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17465.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -173,12 +173,6 @@ tls_ctx_free(struct tls_root_ctx *ctx) |
173 | 173 |
free(ctx->priv_key_pkcs11); |
174 | 174 |
} |
175 | 175 |
#endif |
176 |
-#if defined(MANAGMENT_EXTERNAL_KEY) |
|
177 |
- if (ctx->external_key != NULL) |
|
178 |
- { |
|
179 |
- free(ctx->external_key); |
|
180 |
- } |
|
181 |
-#endif |
|
182 | 176 |
|
183 | 177 |
if (ctx->allowed_ciphers) |
184 | 178 |
{ |
... | ... |
@@ -462,13 +456,6 @@ tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, |
462 | 462 |
return 0; |
463 | 463 |
} |
464 | 464 |
|
465 |
-#ifdef MANAGMENT_EXTERNAL_KEY |
|
466 |
- |
|
467 |
- |
|
468 |
-struct external_context { |
|
469 |
- size_t signature_length; |
|
470 |
-}; |
|
471 |
- |
|
472 | 465 |
/** |
473 | 466 |
* external_pkcs1_sign implements a mbed TLS rsa_sign_func callback, that uses |
474 | 467 |
* the management interface to request an RSA signature for the supplied hash. |
... | ... |
@@ -495,11 +482,9 @@ external_pkcs1_sign( void *ctx_voidptr, |
495 | 495 |
unsigned char *sig ) |
496 | 496 |
{ |
497 | 497 |
struct external_context *const ctx = ctx_voidptr; |
498 |
- char *in_b64 = NULL; |
|
499 |
- char *out_b64 = NULL; |
|
500 | 498 |
int rv; |
501 |
- unsigned char *p = sig; |
|
502 |
- size_t asn_len = 0, oid_size = 0, sig_len = 0; |
|
499 |
+ uint8_t *to_sign = NULL; |
|
500 |
+ size_t asn_len = 0, oid_size = 0; |
|
503 | 501 |
const char *oid = NULL; |
504 | 502 |
|
505 | 503 |
if (NULL == ctx) |
... | ... |
@@ -535,12 +520,14 @@ external_pkcs1_sign( void *ctx_voidptr, |
535 | 535 |
asn_len = 10 + oid_size; |
536 | 536 |
} |
537 | 537 |
|
538 |
- sig_len = ctx->signature_length; |
|
539 |
- if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len) |
|
538 |
+ if ((SIZE_MAX - hashlen) < asn_len |
|
539 |
+ || ctx->signature_length < (asn_len + hashlen)) |
|
540 | 540 |
{ |
541 | 541 |
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
542 | 542 |
} |
543 | 543 |
|
544 |
+ ALLOC_ARRAY_CLEAR(to_sign, uint8_t, asn_len + hashlen); |
|
545 |
+ uint8_t *p = to_sign; |
|
544 | 546 |
if (md_alg != MBEDTLS_MD_NONE) |
545 | 547 |
{ |
546 | 548 |
/* |
... | ... |
@@ -565,34 +552,16 @@ external_pkcs1_sign( void *ctx_voidptr, |
565 | 565 |
*p++ = MBEDTLS_ASN1_OCTET_STRING; |
566 | 566 |
*p++ = hashlen; |
567 | 567 |
|
568 |
- /* Determine added ASN length */ |
|
569 |
- asn_len = p - sig; |
|
568 |
+ /* Double-check ASN length */ |
|
569 |
+ ASSERT(asn_len == p - to_sign); |
|
570 | 570 |
} |
571 | 571 |
|
572 | 572 |
/* Copy the hash to be signed */ |
573 |
- memcpy( p, hash, hashlen ); |
|
574 |
- |
|
575 |
- /* convert 'from' to base64 */ |
|
576 |
- if (openvpn_base64_encode(sig, asn_len + hashlen, &in_b64) <= 0) |
|
577 |
- { |
|
578 |
- rv = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
|
579 |
- goto done; |
|
580 |
- } |
|
573 |
+ memcpy(p, hash, hashlen); |
|
581 | 574 |
|
582 |
- /* call MI for signature */ |
|
583 |
- if (management) |
|
584 |
- { |
|
585 |
- out_b64 = management_query_pk_sig(management, in_b64); |
|
586 |
- } |
|
587 |
- if (!out_b64) |
|
588 |
- { |
|
589 |
- rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; |
|
590 |
- goto done; |
|
591 |
- } |
|
592 |
- |
|
593 |
- /* decode base64 signature to binary and verify length */ |
|
594 |
- if (openvpn_base64_decode(out_b64, sig, ctx->signature_length) != |
|
595 |
- ctx->signature_length) |
|
575 |
+ /* Call external signature function */ |
|
576 |
+ if (!ctx->sign(ctx->sign_ctx, to_sign, asn_len + hashlen, sig, |
|
577 |
+ ctx->signature_length)) |
|
596 | 578 |
{ |
597 | 579 |
rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; |
598 | 580 |
goto done; |
... | ... |
@@ -601,14 +570,7 @@ external_pkcs1_sign( void *ctx_voidptr, |
601 | 601 |
rv = 0; |
602 | 602 |
|
603 | 603 |
done: |
604 |
- if (in_b64) |
|
605 |
- { |
|
606 |
- free(in_b64); |
|
607 |
- } |
|
608 |
- if (out_b64) |
|
609 |
- { |
|
610 |
- free(out_b64); |
|
611 |
- } |
|
604 |
+ free(to_sign); |
|
612 | 605 |
return rv; |
613 | 606 |
} |
614 | 607 |
|
... | ... |
@@ -621,7 +583,8 @@ external_key_len(void *vctx) |
621 | 621 |
} |
622 | 622 |
|
623 | 623 |
int |
624 |
-tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) |
|
624 |
+tls_ctx_use_external_signing_func(struct tls_root_ctx *ctx, |
|
625 |
+ external_sign_func sign_func, void *sign_ctx) |
|
625 | 626 |
{ |
626 | 627 |
ASSERT(NULL != ctx); |
627 | 628 |
|
... | ... |
@@ -631,11 +594,12 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) |
631 | 631 |
return 1; |
632 | 632 |
} |
633 | 633 |
|
634 |
- ALLOC_OBJ_CLEAR(ctx->external_key, struct external_context); |
|
635 |
- ctx->external_key->signature_length = mbedtls_pk_get_len(&ctx->crt_chain->pk); |
|
634 |
+ ctx->external_key.signature_length = mbedtls_pk_get_len(&ctx->crt_chain->pk); |
|
635 |
+ ctx->external_key.sign = sign_func; |
|
636 |
+ ctx->external_key.sign_ctx = sign_ctx; |
|
636 | 637 |
|
637 | 638 |
ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context); |
638 |
- if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ctx->priv_key, ctx->external_key, |
|
639 |
+ if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ctx->priv_key, &ctx->external_key, |
|
639 | 640 |
NULL, external_pkcs1_sign, external_key_len))) |
640 | 641 |
{ |
641 | 642 |
return 1; |
... | ... |
@@ -643,6 +607,47 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) |
643 | 643 |
|
644 | 644 |
return 0; |
645 | 645 |
} |
646 |
+ |
|
647 |
+#ifdef MANAGMENT_EXTERNAL_KEY |
|
648 |
+ |
|
649 |
+/** Query the management interface for a signature, see external_sign_func. */ |
|
650 |
+static bool |
|
651 |
+management_sign_func(void *sign_ctx, const void *src, size_t src_len, |
|
652 |
+ void *dst, size_t dst_len) |
|
653 |
+{ |
|
654 |
+ bool ret = false; |
|
655 |
+ char *src_b64 = NULL; |
|
656 |
+ char *dst_b64 = NULL; |
|
657 |
+ |
|
658 |
+ if (!management || (openvpn_base64_encode(src, src_len, &src_b64) <= 0)) |
|
659 |
+ { |
|
660 |
+ goto cleanup; |
|
661 |
+ } |
|
662 |
+ |
|
663 |
+ if (!(dst_b64 = management_query_pk_sig(management, src_b64))) |
|
664 |
+ { |
|
665 |
+ goto cleanup; |
|
666 |
+ } |
|
667 |
+ |
|
668 |
+ if (openvpn_base64_decode(dst_b64, dst, dst_len) != dst_len) |
|
669 |
+ { |
|
670 |
+ goto cleanup; |
|
671 |
+ } |
|
672 |
+ |
|
673 |
+ ret = true; |
|
674 |
+cleanup: |
|
675 |
+ free (src_b64); |
|
676 |
+ free (dst_b64); |
|
677 |
+ |
|
678 |
+ return ret; |
|
679 |
+} |
|
680 |
+ |
|
681 |
+int |
|
682 |
+tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) |
|
683 |
+{ |
|
684 |
+ return tls_ctx_use_external_signing_func(ctx, management_sign_func, NULL); |
|
685 |
+} |
|
686 |
+ |
|
646 | 687 |
#endif /* ifdef MANAGMENT_EXTERNAL_KEY */ |
647 | 688 |
|
648 | 689 |
void |
... | ... |
@@ -58,6 +58,30 @@ typedef struct { |
58 | 58 |
} bio_ctx; |
59 | 59 |
|
60 | 60 |
/** |
61 |
+ * External signing function prototype. A function pointer to a function |
|
62 |
+ * implementing this prototype is provided to |
|
63 |
+ * tls_ctx_use_external_signing_func(). |
|
64 |
+ * |
|
65 |
+ * @param sign_ctx The context for the signing function. |
|
66 |
+ * @param src The data to be signed, |
|
67 |
+ * @param src_len The length of src, in bytes. |
|
68 |
+ * @param dst The destination buffer for the signature. |
|
69 |
+ * @param dst_len The length of the destination buffer. |
|
70 |
+ * |
|
71 |
+ * @return true if signing succeeded, false otherwise. |
|
72 |
+ */ |
|
73 |
+typedef bool (*external_sign_func)( |
|
74 |
+ void *sign_ctx, const void *src, size_t src_size, |
|
75 |
+ void *dst, size_t dst_size); |
|
76 |
+ |
|
77 |
+/** Context used by external_pkcs1_sign() */ |
|
78 |
+struct external_context { |
|
79 |
+ size_t signature_length; |
|
80 |
+ external_sign_func sign; |
|
81 |
+ void *sign_ctx; |
|
82 |
+}; |
|
83 |
+ |
|
84 |
+/** |
|
61 | 85 |
* Structure that wraps the TLS context. Contents differ depending on the |
62 | 86 |
* SSL library used. |
63 | 87 |
* |
... | ... |
@@ -78,9 +102,7 @@ struct tls_root_ctx { |
78 | 78 |
#if defined(ENABLE_PKCS11) |
79 | 79 |
mbedtls_pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */ |
80 | 80 |
#endif |
81 |
-#ifdef MANAGMENT_EXTERNAL_KEY |
|
82 |
- struct external_context *external_key; /**< Management external key */ |
|
83 |
-#endif |
|
81 |
+ struct external_context external_key; /**< External key context */ |
|
84 | 82 |
int *allowed_ciphers; /**< List of allowed ciphers for this connection */ |
85 | 83 |
mbedtls_x509_crt_profile cert_profile; /**< Allowed certificate types */ |
86 | 84 |
}; |
... | ... |
@@ -91,5 +113,18 @@ struct key_state_ssl { |
91 | 91 |
bio_ctx bio_ctx; |
92 | 92 |
}; |
93 | 93 |
|
94 |
+/** |
|
95 |
+ * Call the supplied signing function to create a TLS signature during the |
|
96 |
+ * TLS handshake. |
|
97 |
+ * |
|
98 |
+ * @param ctx TLS context to use. |
|
99 |
+ * @param sign_func Signing function to call. |
|
100 |
+ * @param sign_ctx Context for the sign function. |
|
101 |
+ * |
|
102 |
+ * @return 0 if successful, 1 if an error occurred. |
|
103 |
+ */ |
|
104 |
+int tls_ctx_use_external_signing_func(struct tls_root_ctx *ctx, |
|
105 |
+ external_sign_func sign_func, |
|
106 |
+ void *sign_ctx); |
|
94 | 107 |
|
95 | 108 |
#endif /* SSL_MBEDTLS_H_ */ |