87
87
#else
88
88
#define APR_USE_OPENSSL_PRE_3_0_API 0
89
89
#endif
90
+ #if OPENSSL_VERSION_NUMBER < 0x30500000L
91
+ #define APR_USE_OPENSSL_PRE_3_5_API 1
92
+ #else
93
+ #define APR_USE_OPENSSL_PRE_3_5_API 0
94
+ #endif
90
95
91
96
#endif /* defined(LIBRESSL_VERSION_NUMBER) */
92
97
93
98
#if APR_USE_OPENSSL_PRE_3_0_API
94
99
#define APR_USE_OPENSSL_ENGINE_API 1
100
+ #define APR_USE_OPENSSL_PROVIDER_API 0
95
101
#else
96
102
#define APR_USE_OPENSSL_ENGINE_API 0
103
+ #define APR_USE_OPENSSL_PROVIDER_API 1
97
104
#endif
98
105
99
106
#if APR_USE_OPENSSL_ENGINE_API
100
107
#include <openssl/engine.h>
101
108
#endif
102
109
110
+ #if APR_USE_OPENSSL_PROVIDER_API
111
+ #include <openssl/provider.h>
112
+ #endif
113
+
103
114
#define LOG_PREFIX "apr_crypto_openssl: "
104
115
105
116
struct apr_crypto_t {
@@ -118,6 +129,9 @@ struct apr_crypto_config_t {
118
129
#else
119
130
void * engine ;
120
131
#endif
132
+ #if APR_USE_OPENSSL_PROVIDER_API
133
+ OSSL_LIB_CTX * libctx ;
134
+ #endif
121
135
};
122
136
123
137
struct apr_crypto_key_t {
@@ -407,6 +421,11 @@ static apr_status_t crypto_cleanup(apr_crypto_t *f)
407
421
ENGINE_free (f -> config -> engine );
408
422
f -> config -> engine = NULL ;
409
423
}
424
+ #endif
425
+ #if APR_USE_OPENSSL_PROVIDER_API
426
+ if (f -> config -> libctx ) {
427
+ OSSL_LIB_CTX_free (f -> config -> libctx );
428
+ }
410
429
#endif
411
430
return APR_SUCCESS ;
412
431
@@ -418,6 +437,15 @@ static apr_status_t crypto_cleanup_helper(void *data)
418
437
return crypto_cleanup (f );
419
438
}
420
439
440
+ #if APR_USE_OPENSSL_PROVIDER_API
441
+ static apr_status_t provider_cleanup (void * data )
442
+ {
443
+ OSSL_PROVIDER * prov = data ;
444
+ OSSL_PROVIDER_unload (prov );
445
+ return APR_SUCCESS ;
446
+ }
447
+ #endif
448
+
421
449
/**
422
450
* @brief Create a context for supporting encryption. Keys, certificates,
423
451
* algorithms and other parameters will be set per context. More than
@@ -452,8 +480,24 @@ static apr_status_t crypto_make(apr_crypto_t **ff,
452
480
char * elt ;
453
481
int i = 0 , j ;
454
482
483
+ #if APR_USE_OPENSSL_PROVIDER_API
484
+ OSSL_PROVIDER * prov = NULL ;
485
+ const char * path = NULL ;
486
+ #endif
487
+
455
488
* ff = NULL ;
456
489
490
+ f = apr_pcalloc (pool , sizeof (apr_crypto_t ));
491
+ if (!f ) {
492
+ return APR_ENOMEM ;
493
+ }
494
+ f -> config = config = apr_pcalloc (pool , sizeof (apr_crypto_config_t ));
495
+ if (!config ) {
496
+ return APR_ENOMEM ;
497
+ }
498
+ f -> pool = pool ;
499
+ f -> provider = provider ;
500
+
457
501
if (params ) {
458
502
if (APR_SUCCESS != (status = apr_tokenize_to_argv (params , & elts , pool ))) {
459
503
return status ;
@@ -481,22 +525,54 @@ static apr_status_t crypto_make(apr_crypto_t **ff,
481
525
}
482
526
}
483
527
528
+ #if APR_USE_OPENSSL_PROVIDER_API
529
+ if (!strcasecmp ("provider-path" , elt )) {
530
+ path = ptr ;
531
+ }
532
+ else if (!strcasecmp ("provider" , elt )) {
533
+
534
+ /* first provider, avoid loading the default by loading null */
535
+ if (!config -> libctx ) {
536
+ prov = OSSL_PROVIDER_load (NULL , "null" );
537
+ config -> libctx = OSSL_LIB_CTX_new ();
538
+ if (!config -> libctx ) {
539
+ return APR_ENOMEM ;
540
+ }
541
+
542
+ apr_pool_cleanup_register (pool , prov , provider_cleanup ,
543
+ apr_pool_cleanup_null );
544
+ }
545
+
546
+ if (path ) {
547
+ OSSL_PROVIDER_set_default_search_path (config -> libctx , path );
548
+ path = NULL ;
549
+ }
550
+
551
+ prov = OSSL_PROVIDER_load (config -> libctx , ptr );
552
+ if (!prov ) {
553
+ return APR_ENOENGINE ;
554
+ }
555
+
556
+ apr_pool_cleanup_register (pool , prov , provider_cleanup ,
557
+ apr_pool_cleanup_null );
558
+ }
559
+ else if (prov ) {
560
+ /* options after a provider apply to the provider */
561
+ #if !APR_USE_OPENSSL_PRE_3_5_API
562
+ if (!OSSL_PROVIDER_add_conf_parameter (prov , elt , ptr )) {
563
+ return PR_EINVAL ;
564
+ }
565
+ #else
566
+ return APR_ENOTIMPL ;
567
+ #endif
568
+ }
569
+ #endif
570
+
484
571
i ++ ;
485
572
}
486
573
engine = fields [0 ].value ;
487
574
}
488
575
489
- f = apr_pcalloc (pool , sizeof (apr_crypto_t ));
490
- if (!f ) {
491
- return APR_ENOMEM ;
492
- }
493
- f -> config = config = apr_pcalloc (pool , sizeof (apr_crypto_config_t ));
494
- if (!config ) {
495
- return APR_ENOMEM ;
496
- }
497
- f -> pool = pool ;
498
- f -> provider = provider ;
499
-
500
576
/* The default/builtin "openssl" engine is the same as NULL though with
501
577
* openssl-3+ it's called something else, keep NULL for that name.
502
578
*/
0 commit comments