Coverage Report

Created: 2026-11-12 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xmlsec/src/openssl/evp.c
Line
Count
Source
1
/**
2
 * XML Security Library (http://www.aleksey.com/xmlsec).
3
 *
4
 * This is free software; see the Copyright file in the source distribution for precise wording.
5
 *
6
 * Copyright (C) 2002-2026 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
7
 */
8
/**
9
 * @addtogroup xmlsec_openssl_crypto
10
 * @brief Private/public (EVP) keys implementation for OpenSSL.
11
 */
12
#include "globals.h"
13
14
#include <string.h>
15
16
#include <openssl/evp.h>
17
18
#include <xmlsec/xmlsec.h>
19
#include <xmlsec/base64.h>
20
#include <xmlsec/keys.h>
21
#include <xmlsec/keyinfo.h>
22
#include <xmlsec/transforms.h>
23
#include <xmlsec/errors.h>
24
#include <xmlsec/private.h>
25
#include <xmlsec/xmltree.h>
26
27
#include <xmlsec/openssl/app.h>
28
#include <xmlsec/openssl/crypto.h>
29
#include <xmlsec/openssl/evp.h>
30
31
#if !defined(XMLSEC_OPENSSL_API_111)
32
#include <openssl/core_names.h>
33
#include <openssl/param_build.h>
34
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
35
36
#include "../cast_helpers.h"
37
#include "../keysdata_helpers.h"
38
#include "openssl_compat.h"
39
#include "private.h"
40
41
42
#if !defined(OPENSSL_NO_ENGINE)
43
#include <openssl/engine.h>
44
#endif /* !defined(OPENSSL_NO_ENGINE) */
45
46
#if !defined(XMLSEC_OPENSSL_API_111)
47
#include <openssl/provider.h>
48
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
49
50
static int
51
0
xmlSecOpenSSLGetBNValue(const xmlSecBufferPtr buf, BIGNUM **bigNum) {
52
0
    xmlSecByte* bufPtr;
53
0
    xmlSecSize bufSize;
54
0
    xmlSecOpenSSLSizeT bufLen;
55
56
0
    xmlSecAssert2(buf != NULL, -1);
57
0
    xmlSecAssert2(bigNum != NULL, -1);
58
59
0
    bufPtr = xmlSecBufferGetData(buf);
60
0
    bufSize = xmlSecBufferGetSize(buf);
61
0
    if((bufPtr == NULL) || (bufSize == 0)) {
62
0
        xmlSecInvalidDataError("BIGNUM value is empty", NULL);
63
0
        return(-1);
64
0
    }
65
0
    XMLSEC_OPENSSL_SAFE_CAST_SIZE_TO_SIZE_T(bufSize, bufLen, return(-1), NULL);
66
67
0
    (*bigNum) = BN_bin2bn(bufPtr, bufLen, (*bigNum));
68
0
    if((*bigNum) == NULL) {
69
0
        xmlSecOpenSSLError2("BN_bin2bn", NULL, "size=" XMLSEC_SIZE_FMT, bufSize);
70
0
        return(-1);
71
0
    }
72
0
    return(0);
73
0
}
74
75
static int
76
0
xmlSecOpenSSLSetBNValue(const BIGNUM *bigNum, xmlSecBufferPtr buf) {
77
0
    xmlSecOpenSSLUInt numBytes;
78
0
    xmlSecOpenSSLSizeT numBytes2;
79
0
    xmlSecByte* bufPtr;
80
0
    xmlSecSize size;
81
0
    int ret;
82
83
0
    xmlSecAssert2(bigNum != NULL, -1);
84
0
    xmlSecAssert2(buf != NULL, -1);
85
86
0
    numBytes = BN_num_bytes(bigNum);
87
0
    if(numBytes <= 0) {
88
0
        xmlSecOpenSSLError("BN_num_bytes", NULL);
89
0
        return(-1);
90
0
    }
91
0
    XMLSEC_OPENSSL_SAFE_CAST_UINT_TO_SIZE(numBytes, size, return(-1), NULL);
92
93
0
    ret = xmlSecBufferSetMaxSize(buf, size);
94
0
    if(ret < 0) {
95
0
        xmlSecInternalError2("xmlSecBufferSetMaxSize", NULL, "size=" XMLSEC_SIZE_FMT, size);
96
0
        return(-1);
97
0
    }
98
99
0
    bufPtr = xmlSecBufferGetData(buf);
100
0
    xmlSecAssert2(bufPtr != NULL, -1);
101
102
0
    numBytes2 = BN_bn2bin(bigNum, bufPtr);
103
0
    if(numBytes2 <= 0) {
104
0
        xmlSecOpenSSLError("BN_bn2bin", NULL);
105
0
        return(-1);
106
0
    }
107
0
    XMLSEC_OPENSSL_SAFE_CAST_SIZE_T_TO_SIZE(numBytes2, size, return(-1), NULL);
108
109
0
    ret = xmlSecBufferSetSize(buf, size);
110
0
    if(ret < 0) {
111
0
        xmlSecInternalError2("xmlSecBufferSetSize", NULL, "size=" XMLSEC_SIZE_FMT, size);
112
0
        return(-1);
113
0
    }
114
115
0
    return(0);
116
0
}
117
118
/******************************************************************************
119
 *
120
 * Internal OpenSSL EVP key CTX
121
 *
122
 *****************************************************************************/
123
typedef struct _xmlSecOpenSSLEvpKeyDataCtx      xmlSecOpenSSLEvpKeyDataCtx,
124
                                                *xmlSecOpenSSLEvpKeyDataCtxPtr;
125
struct _xmlSecOpenSSLEvpKeyDataCtx {
126
    EVP_PKEY*           pKey;
127
};
128
129
/******************************************************************************
130
 *
131
 * EVP key data
132
 *
133
 *****************************************************************************/
134
456
XMLSEC_KEY_DATA_DECLARE(OpenSSLEvpKeyData, xmlSecOpenSSLEvpKeyDataCtx)
135
456
#define xmlSecOpenSSLEvpKeyDataSize XMLSEC_KEY_DATA_SIZE(OpenSSLEvpKeyData)
136
456
137
456
static int               xmlSecOpenSSLEvpKeyDataInitialize       (xmlSecKeyDataPtr data);
138
456
static int               xmlSecOpenSSLEvpKeyDataDuplicate        (xmlSecKeyDataPtr dst,
139
456
                                                                 xmlSecKeyDataPtr src);
140
456
static void              xmlSecOpenSSLEvpKeyDataFinalize         (xmlSecKeyDataPtr data);
141
456
static xmlSecSize        xmlSecOpenSSLEvpKeyDataGetKeySize       (xmlSecKeyDataPtr data);
142
456
static xmlSecKeyDataType xmlSecOpenSSLEvpKeyDataGetType          (xmlSecKeyDataPtr data);
143
456
static int               xmlSecOpenSSLEvpKeyDataKlassCheck       (xmlSecKeyDataKlass* klass);
144
456
145
456
#define xmlSecOpenSSLEvpKeyDataCheckId(data) \
146
456
    (xmlSecKeyDataIsValid((data)) && \
147
456
     xmlSecOpenSSLEvpKeyDataKlassCheck((data)->id))
148
456
149
456
150
456
151
456
/**
152
456
 * @brief Sets the value of key data.
153
456
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
154
456
 * @param data the pointer to OpenSSL EVP key data.
155
456
 * @param pKey the pointer to EVP key.
156
456
 * @return 0 on success or a negative value otherwise.
157
456
 */
158
456
int
159
456
xmlSecOpenSSLEvpKeyDataAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
160
39
    xmlSecOpenSSLEvpKeyDataCtxPtr ctx;
161
162
39
    xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
163
39
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecOpenSSLEvpKeyDataSize), -1);
164
39
    xmlSecAssert2(pKey != NULL, -1);
165
166
39
    ctx = xmlSecOpenSSLEvpKeyDataGetCtx(data);
167
39
    xmlSecAssert2(ctx != NULL, -1);
168
169
39
    if(ctx->pKey != NULL) {
170
0
        EVP_PKEY_free(ctx->pKey);
171
0
    }
172
39
    ctx->pKey = pKey;
173
39
    return(0);
174
39
}
175
176
/**
177
 * @brief Gets the EVP_PKEY from the key data.
178
 * @details Returns NULL if the key data is not an OpenSSL EVP key data object.
179
 * @param data the pointer to OpenSSL EVP data.
180
 * @return a borrowed pointer to EVP_PKEY, or NULL if an error occurs; the caller must NOT free it.
181
 */
182
EVP_PKEY*
183
4
xmlSecOpenSSLEvpKeyDataGetEvp(xmlSecKeyDataPtr data) {
184
4
    xmlSecOpenSSLEvpKeyDataCtxPtr ctx;
185
186
4
    xmlSecAssert2(xmlSecOpenSSLEvpKeyDataCheckId(data), NULL);
187
188
4
    ctx = xmlSecOpenSSLEvpKeyDataGetCtx(data);
189
4
    xmlSecAssert2(ctx != NULL, NULL);
190
191
4
    return(ctx->pKey);
192
4
}
193
194
/**
195
 * @brief Gets the EVP_PKEY from the key.
196
 * @details Returns NULL if the key has no value or the value is not an OpenSSL EVP key data object.
197
 * @param key the pointer to OpenSSL EVP key.
198
 * @return a borrowed pointer to EVP_PKEY, or NULL if an error occurs; the caller must NOT free it.
199
 */
200
EVP_PKEY*
201
0
xmlSecOpenSSLKeyGetEvp(xmlSecKeyPtr key) {
202
0
    xmlSecKeyDataPtr value;
203
204
0
    xmlSecAssert2(key != NULL, NULL);
205
206
0
    value = xmlSecKeyGetValue(key);
207
0
    if(value == NULL) {
208
        /* key value might not have been set yet */
209
0
        return(NULL);
210
0
    }
211
0
    return(xmlSecOpenSSLEvpKeyDataGetEvp(value));
212
0
}
213
214
static int
215
47
xmlSecOpenSSLEvpKeyDataInitialize(xmlSecKeyDataPtr data) {
216
47
    xmlSecOpenSSLEvpKeyDataCtxPtr ctx;
217
218
47
    xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
219
47
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecOpenSSLEvpKeyDataSize), -1);
220
221
47
    ctx = xmlSecOpenSSLEvpKeyDataGetCtx(data);
222
47
    xmlSecAssert2(ctx != NULL, -1);
223
224
47
    memset(ctx, 0, sizeof(xmlSecOpenSSLEvpKeyDataCtx));
225
226
47
    return(0);
227
47
}
228
229
static int
230
8
xmlSecOpenSSLEvpKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
231
8
    xmlSecOpenSSLEvpKeyDataCtxPtr ctxDst;
232
8
    xmlSecOpenSSLEvpKeyDataCtxPtr ctxSrc;
233
234
8
    xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1);
235
8
    xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecOpenSSLEvpKeyDataSize), -1);
236
8
    xmlSecAssert2(xmlSecKeyDataIsValid(src), -1);
237
8
    xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecOpenSSLEvpKeyDataSize), -1);
238
8
    xmlSecAssert2(src->id == dst->id, -1);
239
240
8
    ctxDst = xmlSecOpenSSLEvpKeyDataGetCtx(dst);
241
8
    xmlSecAssert2(ctxDst != NULL, -1);
242
8
    xmlSecAssert2(ctxDst->pKey == NULL, -1);
243
244
8
    ctxSrc = xmlSecOpenSSLEvpKeyDataGetCtx(src);
245
8
    xmlSecAssert2(ctxSrc != NULL, -1);
246
247
8
    if(ctxSrc->pKey != NULL) {
248
8
        ctxDst->pKey = xmlSecOpenSSLEvpKeyDup(ctxSrc->pKey);
249
8
        if(ctxDst->pKey == NULL) {
250
0
            xmlSecInternalError("xmlSecOpenSSLEvpKeyDup",
251
0
                                xmlSecKeyDataGetName(dst));
252
0
            return(-1);
253
0
        }
254
8
    }
255
256
    /* done */
257
8
    return(0);
258
8
}
259
260
static void
261
46
xmlSecOpenSSLEvpKeyDataFinalize(xmlSecKeyDataPtr data) {
262
46
    xmlSecOpenSSLEvpKeyDataCtxPtr ctx;
263
264
46
    xmlSecAssert(xmlSecKeyDataIsValid(data));
265
46
    xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecOpenSSLEvpKeyDataSize));
266
267
46
    ctx = xmlSecOpenSSLEvpKeyDataGetCtx(data);
268
46
    xmlSecAssert(ctx != NULL);
269
270
46
    if(ctx->pKey != NULL) {
271
46
        EVP_PKEY_free(ctx->pKey);
272
46
    }
273
46
    OPENSSL_cleanse(ctx, sizeof(xmlSecOpenSSLEvpKeyDataCtx));
274
46
}
275
276
#if !defined(XMLSEC_OPENSSL_API_111)
277
278
static xmlSecSize
279
0
xmlSecOpenSSLEvpKeyDataGetKeySize(xmlSecKeyDataPtr data) {
280
0
    EVP_PKEY* pKey;
281
0
    xmlSecSize res;
282
0
    int ret;
283
284
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
285
0
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecOpenSSLEvpKeyDataSize), 0);
286
287
0
    pKey = xmlSecOpenSSLEvpKeyDataGetEvp(data);
288
0
    xmlSecAssert2(pKey != NULL, 0);
289
290
0
    ret = EVP_PKEY_get_bits(pKey);
291
0
    if(ret <= 0) {
292
0
        xmlSecOpenSSLError("EVP_PKEY_get_bits", xmlSecKeyDataGetName(data));
293
0
        return(0);
294
0
    }
295
296
0
    XMLSEC_SAFE_CAST_INT_TO_SIZE(ret, res, return(0), xmlSecKeyDataGetName(data));
297
0
    return(res);
298
0
}
299
300
static xmlSecKeyDataType
301
24
xmlSecOpenSSLEvpKeyDataGetType(xmlSecKeyDataPtr data) {
302
24
    xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
303
24
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecOpenSSLEvpKeyDataSize), xmlSecKeyDataTypeUnknown);
304
305
    /* there is no good way to determine if a key is public or private so
306
     * we assume it is private (see https://github.com/lsh123/xmlsec/issues/588)
307
     */
308
24
    return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
309
24
}
310
#else /* !defined(XMLSEC_OPENSSL_API_111) */
311
static xmlSecSize
312
xmlSecOpenSSLEvpKeyDataGetKeySize(xmlSecKeyDataPtr data) {
313
    EVP_PKEY* pKey;
314
315
    xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
316
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecOpenSSLEvpKeyDataSize), 0);
317
318
    pKey = xmlSecOpenSSLEvpKeyDataGetEvp(data);
319
    xmlSecAssert2(pKey != NULL, 0);
320
321
    switch(EVP_PKEY_base_id(pKey)) {
322
#ifndef XMLSEC_NO_RSA
323
    case EVP_PKEY_RSA:
324
    case EVP_PKEY_RSA2:
325
    case EVP_PKEY_RSA_PSS:
326
        {
327
            RSA* rsa = NULL;
328
            const BIGNUM* n = NULL;
329
            xmlSecOpenSSLSizeT numBits;
330
            xmlSecSize res;
331
332
            rsa = EVP_PKEY_get0_RSA(pKey);
333
            if(rsa == NULL) {
334
                xmlSecOpenSSLError("EVP_PKEY_get0_RSA", xmlSecKeyDataGetName(data));
335
                return(0);
336
            }
337
338
            RSA_get0_key(rsa, &n, NULL, NULL);
339
            if(n == NULL) {
340
                xmlSecOpenSSLError("RSA_get0_key", xmlSecKeyDataGetName(data));
341
                return(0);
342
            }
343
344
            numBits = BN_num_bits(n);
345
            if(numBits <= 0) {
346
                xmlSecOpenSSLError("BN_num_bits", xmlSecKeyDataGetName(data));
347
                return(0);
348
            }
349
350
            XMLSEC_OPENSSL_SAFE_CAST_SIZE_T_TO_SIZE(numBits, res, return(0), xmlSecKeyDataGetName(data));
351
            return(res);
352
        }
353
#endif /* XMLSEC_NO_RSA */
354
355
#ifndef XMLSEC_NO_DSA
356
    case EVP_PKEY_DSA:
357
        {
358
            DSA* dsa = NULL;
359
            const BIGNUM* p = NULL;
360
            int numBits;
361
            xmlSecSize res;
362
363
            dsa = EVP_PKEY_get0_DSA(pKey);
364
            if(dsa == NULL) {
365
                xmlSecOpenSSLError("EVP_PKEY_get0_DSA", xmlSecKeyDataGetName(data));
366
                return(0);
367
            }
368
369
            DSA_get0_pqg(dsa, &p, NULL, NULL);
370
            if(p == NULL) {
371
                xmlSecOpenSSLError("DSA_get0_pqg", xmlSecKeyDataGetName(data));
372
                return(0);
373
            }
374
375
            numBits = BN_num_bits(p);
376
            if(numBits <= 0) {
377
                xmlSecOpenSSLError("BN_num_bits", xmlSecKeyDataGetName(data));
378
                return(0);
379
            }
380
381
            XMLSEC_SAFE_CAST_INT_TO_SIZE(numBits, res, return(0), xmlSecKeyDataGetName(data));
382
            return(res);
383
        }
384
#endif /* XMLSEC_NO_DSA */
385
386
#ifndef XMLSEC_NO_DH
387
    case EVP_PKEY_DH:
388
    case EVP_PKEY_DHX:
389
        {
390
            DH* dh = NULL;
391
            const BIGNUM* p = NULL;
392
            int numBits;
393
            xmlSecSize res;
394
395
            dh = EVP_PKEY_get0_DH(pKey);
396
            if(dh == NULL) {
397
                xmlSecOpenSSLError("EVP_PKEY_get0_DH", xmlSecKeyDataGetName(data));
398
                return(0);
399
            }
400
401
            DH_get0_pqg(dh, &p, NULL, NULL);
402
            if(p == NULL) {
403
                xmlSecOpenSSLError("DH_get0_pqg", xmlSecKeyDataGetName(data));
404
                return(0);
405
            }
406
407
            numBits = BN_num_bits(p);
408
            if(numBits <= 0) {
409
                xmlSecOpenSSLError("BN_num_bits", xmlSecKeyDataGetName(data));
410
                return(0);
411
            }
412
413
            XMLSEC_SAFE_CAST_INT_TO_SIZE(numBits, res, return(0), xmlSecKeyDataGetName(data));
414
            return(res);
415
        }
416
#endif /* XMLSEC_NO_DH */
417
418
#ifndef XMLSEC_NO_EC
419
    case EVP_PKEY_EC:
420
        {
421
            const EC_KEY* ecKey = NULL;
422
            const EC_GROUP* group = NULL;
423
            BIGNUM* order = NULL;
424
            xmlSecOpenSSLUInt numBits;
425
            xmlSecSize res = 0;
426
            int ret;
427
428
            ecKey = EVP_PKEY_get0_EC_KEY(pKey);
429
            if(ecKey == NULL) {
430
                xmlSecOpenSSLError("EVP_PKEY_get0_EC_KEY", xmlSecKeyDataGetName(data));
431
                return(0);
432
            }
433
434
            group = EC_KEY_get0_group(ecKey);
435
            if(group == NULL) {
436
                xmlSecOpenSSLError("EC_KEY_get0_group", xmlSecKeyDataGetName(data));
437
                return(0);
438
            }
439
440
            order = BN_new();
441
            if(order == NULL) {
442
                xmlSecOpenSSLError("BN_new", xmlSecKeyDataGetName(data));
443
                return(0);
444
            }
445
446
            ret = EC_GROUP_get_order(group, order, NULL);
447
            if(ret != 1) {
448
                xmlSecOpenSSLError("EC_GROUP_get_order", xmlSecKeyDataGetName(data));
449
                BN_clear_free(order);
450
                return(0);
451
            }
452
453
            numBits = BN_num_bits(order);
454
            BN_clear_free(order);
455
            if(numBits <= 0) {
456
                xmlSecOpenSSLError("BN_num_bits", xmlSecKeyDataGetName(data));
457
                return(0);
458
            }
459
460
            XMLSEC_OPENSSL_SAFE_CAST_UINT_TO_SIZE(numBits, res, return(0), xmlSecKeyDataGetName(data));
461
            return(res);
462
        }
463
#endif /* XMLSEC_NO_EC */
464
465
#ifndef XMLSEC_NO_GOST
466
    case NID_id_GostR3410_2001:
467
        return(512);
468
#endif /* XMLSEC_NO_GOST */
469
470
#ifndef XMLSEC_NO_GOST2012
471
    case NID_id_GostR3410_2012_256:
472
        return(512);
473
    case NID_id_GostR3410_2012_512:
474
        return(1024);
475
#endif /* XMLSEC_NO_GOST2012 */
476
477
#ifndef XMLSEC_NO_EDDSA
478
    /* key sizes match the values returned by EVP_PKEY_get_bits() on OpenSSL 3.0+ */
479
    case EVP_PKEY_ED25519:
480
        return(256);
481
    case EVP_PKEY_ED448:
482
        return(456);
483
#endif /* XMLSEC_NO_EDDSA */
484
485
#ifndef XMLSEC_NO_XDH
486
    case EVP_PKEY_X25519:
487
        return(253);
488
    case EVP_PKEY_X448:
489
        return(448);
490
#endif /* XMLSEC_NO_XDH */
491
492
    default:
493
        {
494
            /* for other keys we don't have a good way to get the key size, so return 0 */
495
            xmlSecOpenSSLError2("EVP_PKEY_base_id", xmlSecKeyDataGetName(data),
496
                "unsupported evp key type=%d", EVP_PKEY_base_id(pKey));
497
            return(0);
498
        }
499
    }
500
}
501
502
static xmlSecKeyDataType
503
xmlSecOpenSSLEvpKeyDataGetType(xmlSecKeyDataPtr data) {
504
    EVP_PKEY* pKey;
505
506
    xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
507
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecOpenSSLEvpKeyDataSize), xmlSecKeyDataTypeUnknown);
508
509
    pKey = xmlSecOpenSSLEvpKeyDataGetEvp(data);
510
    xmlSecAssert2(pKey != NULL, xmlSecKeyDataTypeUnknown);
511
512
    /* check if the key is in memory */
513
#if !defined(OPENSSL_NO_ENGINE)
514
    if (EVP_PKEY_get0_engine(pKey) != NULL) {
515
        /* there is no way to determine if a key is public or private when
516
         * key is stored on HSM (engine or provider) so we assume it is private
517
         * (see https://github.com/lsh123/xmlsec/issues/588)
518
         */
519
        return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
520
    }
521
#endif /* !defined(OPENSSL_NO_ENGINE) */
522
523
    switch(EVP_PKEY_base_id(pKey)) {
524
#ifndef XMLSEC_NO_RSA
525
    case EVP_PKEY_RSA:
526
    case EVP_PKEY_RSA2:
527
    case EVP_PKEY_RSA_PSS:
528
        {
529
            RSA* rsa = NULL;
530
            const BIGNUM* dd = NULL;
531
532
            rsa = EVP_PKEY_get0_RSA(pKey);
533
            if(rsa == NULL) {
534
                xmlSecOpenSSLError("EVP_PKEY_get0_RSA", xmlSecKeyDataGetName(data));
535
                return(xmlSecKeyDataTypeUnknown);
536
            }
537
538
            RSA_get0_key(rsa, NULL, NULL, &dd);
539
            if(dd != NULL) {
540
                return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
541
            } else {
542
                return(xmlSecKeyDataTypePublic);
543
            }
544
        }
545
#endif /* XMLSEC_NO_RSA */
546
547
#ifndef XMLSEC_NO_DSA
548
    case EVP_PKEY_DSA:
549
        {
550
            DSA* dsa = NULL;
551
            const BIGNUM* priv_key = NULL;
552
553
            dsa = EVP_PKEY_get0_DSA(pKey);
554
            if(dsa == NULL) {
555
                xmlSecOpenSSLError("EVP_PKEY_get0_DSA", xmlSecKeyDataGetName(data));
556
                return(xmlSecKeyDataTypeUnknown);
557
            }
558
559
            DSA_get0_key(dsa, NULL, &priv_key);
560
            if(priv_key != NULL) {
561
                return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
562
            } else {
563
                return(xmlSecKeyDataTypePublic);
564
            }
565
        }
566
#endif /* XMLSEC_NO_DSA */
567
568
#ifndef XMLSEC_NO_DH
569
    case EVP_PKEY_DH:
570
    case EVP_PKEY_DHX:
571
        {
572
            DH* dh = NULL;
573
            const BIGNUM* priv_key = NULL;
574
575
            dh = EVP_PKEY_get0_DH(pKey);
576
            if(dh == NULL) {
577
                xmlSecOpenSSLError("EVP_PKEY_get0_DH", xmlSecKeyDataGetName(data));
578
                return(xmlSecKeyDataTypeUnknown);
579
            }
580
581
            DH_get0_key(dh, NULL, &priv_key);
582
            if(priv_key != NULL) {
583
                return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
584
            } else {
585
                return(xmlSecKeyDataTypePublic);
586
            }
587
        }
588
#endif /* XMLSEC_NO_DH */
589
590
#ifndef XMLSEC_NO_EC
591
    case EVP_PKEY_EC:
592
        {
593
            const EC_KEY* ecKey = NULL;
594
595
            ecKey = EVP_PKEY_get0_EC_KEY(pKey);
596
            if(ecKey == NULL) {
597
                xmlSecOpenSSLError("EVP_PKEY_get0_EC_KEY", xmlSecKeyDataGetName(data));
598
                return(xmlSecKeyDataTypeUnknown);
599
            }
600
601
            if(EC_KEY_get0_private_key(ecKey) != NULL) {
602
                return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
603
            } else {
604
                return(xmlSecKeyDataTypePublic);
605
            }
606
        }
607
#endif /* XMLSEC_NO_EC */
608
609
#ifndef XMLSEC_NO_GOST
610
    case NID_id_GostR3410_2001:
611
        /* I don't know how to find whether we have both private and public key
612
        or the public only (see https://github.com/lsh123/xmlsec/issues/588) */
613
        return(xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
614
#endif /* XMLSEC_NO_GOST */
615
616
#ifndef XMLSEC_NO_GOST2012
617
    case NID_id_GostR3410_2012_256:
618
    case NID_id_GostR3410_2012_512:
619
        /* I don't know how to find whether we have both private and public key
620
        or the public only (see https://github.com/lsh123/xmlsec/issues/588) */
621
        return(xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
622
#endif /* XMLSEC_NO_GOST2012 */
623
624
#ifndef XMLSEC_NO_EDDSA
625
    case EVP_PKEY_ED25519:
626
    case EVP_PKEY_ED448:
627
        /* I don't know how to find whether we have both private and public key
628
        or the public only (see https://github.com/lsh123/xmlsec/issues/588) */
629
        return(xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
630
#endif /* XMLSEC_NO_EDDSA */
631
632
#ifndef XMLSEC_NO_XDH
633
    case EVP_PKEY_X25519:
634
    case EVP_PKEY_X448:
635
        /* I don't know how to find whether we have both private and public key
636
        or the public only (see https://github.com/lsh123/xmlsec/issues/588) */
637
        return(xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
638
#endif /* XMLSEC_NO_XDH */
639
640
    default:
641
        {
642
            /* for other keys we don't have a good way to get the key type, so return the unknown key type */
643
            xmlSecOpenSSLError2("EVP_PKEY_base_id", xmlSecKeyDataGetName(data),
644
                "unsupported evp key type=%d", EVP_PKEY_base_id(pKey));
645
            return(xmlSecKeyDataTypeUnknown);
646
        }
647
    }
648
}
649
650
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
651
652
static int
653
4
xmlSecOpenSSLEvpKeyDataKlassCheck(xmlSecKeyDataKlass* klass) {
654
655
4
#ifndef XMLSEC_NO_DSA
656
4
    if(klass == xmlSecOpenSSLKeyDataDsaId) {
657
0
        return(1);
658
0
    }
659
4
#endif /* XMLSEC_NO_DSA */
660
661
4
#ifndef XMLSEC_NO_DH
662
4
    if(klass == xmlSecOpenSSLKeyDataDhId) {
663
0
        return(1);
664
0
    }
665
4
#endif /* XMLSEC_NO_DH */
666
667
4
#ifndef XMLSEC_NO_EC
668
4
    if(klass == xmlSecOpenSSLKeyDataEcId) {
669
0
        return(1);
670
0
    }
671
4
#endif /* XMLSEC_NO_EC */
672
673
#ifndef XMLSEC_NO_GOST
674
    if(klass == xmlSecOpenSSLKeyDataGost2001Id) {
675
        return(1);
676
    }
677
#endif /* XMLSEC_NO_GOST */
678
679
#ifndef XMLSEC_NO_GOST2012
680
    if(klass == xmlSecOpenSSLKeyDataGostR3410_2012_256Id) {
681
        return(1);
682
    }
683
    if(klass == xmlSecOpenSSLKeyDataGostR3410_2012_512Id) {
684
        return(1);
685
    }
686
#endif /* XMLSEC_NO_GOST2012 */
687
688
4
#ifndef XMLSEC_NO_RSA
689
4
    if(klass == xmlSecOpenSSLKeyDataRsaId) {
690
4
        return(1);
691
4
    }
692
0
#endif /* XMLSEC_NO_RSA */
693
694
#ifndef XMLSEC_NO_MLDSA
695
    if(klass == xmlSecOpenSSLKeyDataMLDSAId) {
696
        return(1);
697
    }
698
#endif /* XMLSEC_NO_MLDSA */
699
700
#ifndef XMLSEC_NO_MLKEM
701
    if(klass == xmlSecOpenSSLKeyDataMLKEMId) {
702
        return(1);
703
    }
704
#endif /* XMLSEC_NO_MLKEM */
705
706
#ifndef XMLSEC_NO_SLHDSA
707
    if(klass == xmlSecOpenSSLKeyDataSLHDSAId) {
708
        return(1);
709
    }
710
#endif /* XMLSEC_NO_SLHDSA */
711
712
#ifndef XMLSEC_NO_EDDSA
713
    if(klass == xmlSecOpenSSLKeyDataEdDSAId) {
714
        return(1);
715
    }
716
#endif /* XMLSEC_NO_EDDSA */
717
718
0
#ifndef XMLSEC_NO_XDH
719
0
    if(klass == xmlSecOpenSSLKeyDataXdhId) {
720
0
        return(1);
721
0
    }
722
0
#endif /* XMLSEC_NO_XDH */
723
724
0
    return(0);
725
0
}
726
727
728
/******************************************************************************
729
 *
730
 * EVP helper functions
731
 *
732
 *****************************************************************************/
733
/**
734
 * @brief Increments the reference count of @p pKey.
735
 * @param pKey the pointer to EVP_PKEY.
736
 * @return the same EVP_PKEY with its reference count incremented, or NULL if an error occurs.
737
 */
738
EVP_PKEY*
739
8
xmlSecOpenSSLEvpKeyDup(EVP_PKEY* pKey) {
740
8
    int ret;
741
742
8
    xmlSecAssert2(pKey != NULL, NULL);
743
744
8
    ret = EVP_PKEY_up_ref(pKey);
745
8
    if(ret <= 0) {
746
0
        xmlSecOpenSSLError("EVP_PKEY_up_ref", NULL);
747
0
        return(NULL);
748
0
    }
749
750
8
    return(pKey);
751
8
}
752
753
#if !defined(XMLSEC_OPENSSL_API_111)
754
755
/* newer implementations don't have id because they use EVP_KEYMGMT */
756
static int
757
41
xmlSecOpenSSLEvpKeyGetId(EVP_PKEY *pKey) {
758
41
    const char * typeName;
759
41
    int id;
760
761
41
    xmlSecAssert2(pKey != NULL, EVP_PKEY_NONE);
762
763
41
    id = EVP_PKEY_base_id(pKey);
764
41
    if(id != EVP_PKEY_NONE) {
765
41
        return(id);
766
41
    }
767
0
    typeName = EVP_PKEY_get0_type_name(pKey);
768
0
    if(typeName != NULL) {
769
#ifndef XMLSEC_NO_MLDSA
770
        if(strcmp(LN_ML_DSA_44, typeName) == 0) {
771
            return (EVP_PKEY_ML_DSA_44);
772
        } else if(strcmp(LN_ML_DSA_65, typeName) == 0) {
773
            return (EVP_PKEY_ML_DSA_65);
774
        } else if(strcmp(LN_ML_DSA_87, typeName) == 0) {
775
            return (EVP_PKEY_ML_DSA_87);
776
        }
777
#endif /* XMLSEC_NO_MLDSA */
778
779
#ifndef XMLSEC_NO_MLKEM
780
        if(strcmp(LN_ML_KEM_512, typeName) == 0) {
781
            return (NID_ML_KEM_512);
782
        } else if(strcmp(LN_ML_KEM_768, typeName) == 0) {
783
            return (NID_ML_KEM_768);
784
        } else if(strcmp(LN_ML_KEM_1024, typeName) == 0) {
785
            return (NID_ML_KEM_1024);
786
        }
787
#endif /* XMLSEC_NO_MLKEM */
788
789
#ifndef XMLSEC_NO_SLHDSA
790
        if(strcmp(LN_SLH_DSA_SHA2_128f, typeName) == 0) {
791
            return (EVP_PKEY_SLH_DSA_SHA2_128F);
792
        } else if(strcmp(LN_SLH_DSA_SHA2_128s, typeName) == 0) {
793
            return (EVP_PKEY_SLH_DSA_SHA2_128S);
794
        } else if(strcmp(LN_SLH_DSA_SHA2_192f, typeName) == 0) {
795
            return (EVP_PKEY_SLH_DSA_SHA2_192F);
796
        } else if(strcmp(LN_SLH_DSA_SHA2_192s, typeName) == 0) {
797
            return (EVP_PKEY_SLH_DSA_SHA2_192S);
798
        } else if(strcmp(LN_SLH_DSA_SHA2_256f, typeName) == 0) {
799
            return (EVP_PKEY_SLH_DSA_SHA2_256F);
800
        } else if(strcmp(LN_SLH_DSA_SHA2_256s, typeName) == 0) {
801
            return (EVP_PKEY_SLH_DSA_SHA2_256S);
802
        }
803
#endif /* XMLSEC_NO_SLHDSA */
804
805
0
    }
806
807
    /* no luck */
808
0
    return(EVP_PKEY_NONE);
809
41
}
810
811
#else /* !defined(XMLSEC_OPENSSL_API_111) */
812
813
#define xmlSecOpenSSLEvpKeyGetId(pKey)  EVP_PKEY_base_id(pKey)
814
815
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
816
817
818
static xmlSecKeyDataId
819
40
xmlSecOpenSSLEvpKeyGetKeyDataId(EVP_PKEY *pKey) {
820
821
40
    xmlSecAssert2(pKey != NULL, NULL);
822
823
40
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
824
0
#ifndef XMLSEC_NO_DH
825
0
    case EVP_PKEY_DH:
826
0
    case EVP_PKEY_DHX:
827
0
        return (xmlSecOpenSSLKeyDataDhId);
828
0
#endif /* XMLSEC_NO_DH */
829
830
0
#ifndef XMLSEC_NO_DSA
831
16
    case EVP_PKEY_DSA:
832
16
        return (xmlSecOpenSSLKeyDataDsaId);
833
0
#endif /* XMLSEC_NO_DSA */
834
835
0
#ifndef XMLSEC_NO_EC
836
0
    case EVP_PKEY_EC:
837
0
        return (xmlSecOpenSSLKeyDataEcId);
838
0
#endif /* XMLSEC_NO_EC */
839
840
#ifndef XMLSEC_NO_GOST
841
    case NID_id_GostR3410_2001:
842
        return (xmlSecOpenSSLKeyDataGost2001Id);
843
#endif /* XMLSEC_NO_GOST */
844
845
#ifndef XMLSEC_NO_GOST2012
846
    case NID_id_GostR3410_2012_256:
847
        return (xmlSecOpenSSLKeyDataGostR3410_2012_256Id);
848
849
    case NID_id_GostR3410_2012_512:
850
        return (xmlSecOpenSSLKeyDataGostR3410_2012_512Id);
851
#endif /* XMLSEC_NO_GOST2012 */
852
853
#ifndef XMLSEC_NO_MLDSA
854
    case EVP_PKEY_ML_DSA_44:
855
    case EVP_PKEY_ML_DSA_65:
856
    case EVP_PKEY_ML_DSA_87:
857
        return (xmlSecOpenSSLKeyDataMLDSAId);
858
#endif /* XMLSEC_NO_MLDSA */
859
860
#ifndef XMLSEC_NO_MLKEM
861
    case NID_ML_KEM_512:
862
    case NID_ML_KEM_768:
863
    case NID_ML_KEM_1024:
864
        return (xmlSecOpenSSLKeyDataMLKEMId);
865
#endif /* XMLSEC_NO_MLKEM */
866
867
#ifndef XMLSEC_NO_SLHDSA
868
    case EVP_PKEY_SLH_DSA_SHA2_128F:
869
    case EVP_PKEY_SLH_DSA_SHA2_128S:
870
    case EVP_PKEY_SLH_DSA_SHA2_192F:
871
    case EVP_PKEY_SLH_DSA_SHA2_192S:
872
    case EVP_PKEY_SLH_DSA_SHA2_256F:
873
    case EVP_PKEY_SLH_DSA_SHA2_256S:
874
        return (xmlSecOpenSSLKeyDataSLHDSAId);
875
#endif /* XMLSEC_NO_SLHDSA */
876
877
#ifndef XMLSEC_NO_EDDSA
878
    case EVP_PKEY_ED25519:
879
    case EVP_PKEY_ED448:
880
        return (xmlSecOpenSSLKeyDataEdDSAId);
881
#endif /* XMLSEC_NO_EDDSA */
882
883
0
#ifndef XMLSEC_NO_XDH
884
20
    case EVP_PKEY_X25519:
885
21
    case EVP_PKEY_X448:
886
21
        return (xmlSecOpenSSLKeyDataXdhId);
887
0
#endif /* XMLSEC_NO_XDH */
888
889
0
#ifndef XMLSEC_NO_RSA
890
2
    case EVP_PKEY_RSA:
891
2
    case EVP_PKEY_RSA2:
892
2
    case EVP_PKEY_RSA_PSS:
893
2
        return (xmlSecOpenSSLKeyDataRsaId);
894
40
#endif /* XMLSEC_NO_RSA */
895
40
    }
896
897
    /* no luck */
898
1
    return(NULL);
899
40
}
900
901
/**
902
 * @brief Creates xmlsec key data object from OpenSSL key object.
903
 * @details On success, ownership of @p pKey transfers to the returned key data; on failure the caller retains ownership.
904
 * @param pKey the pointer to EVP_PKEY.
905
 * @return pointer to the newly created xmlsec key data or NULL if an error occurs.
906
 */
907
xmlSecKeyDataPtr
908
40
xmlSecOpenSSLEvpKeyAdopt(EVP_PKEY *pKey) {
909
40
    xmlSecKeyDataPtr data = NULL;
910
40
    xmlSecKeyDataId id;
911
40
    int ret;
912
913
40
    xmlSecAssert2(pKey != NULL, NULL);
914
915
40
    id = xmlSecOpenSSLEvpKeyGetKeyDataId(pKey);
916
40
    if(id == NULL) {
917
1
        xmlSecInvalidIntegerTypeError("evp key type", xmlSecOpenSSLEvpKeyGetId(pKey), "unsupported evp key type", NULL);
918
1
        return(NULL);
919
1
    }
920
921
39
    data = xmlSecKeyDataCreate(id);
922
39
    if(data == NULL) {
923
0
        xmlSecInternalError("xmlSecKeyDataCreate", NULL);
924
0
        return(NULL);
925
0
    }
926
927
39
    ret = xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey);
928
39
    if(ret < 0) {
929
0
        xmlSecInternalError("xmlSecOpenSSLEvpKeyDataAdoptEvp", NULL);
930
0
        xmlSecKeyDataDestroy(data);
931
0
        return(NULL);
932
0
    }
933
39
    pKey = NULL;
934
935
39
    return(data);
936
39
}
937
938
939
/* Helper macro to define the key data klass */
940
#define XMLSEC_OPENSSL_EVP_KEY_KLASS_EX2(klassName, keyName, keyHref, usage, dataNodeName, dataNodeNs, generate, xmlRead, xmlWrite)  \
941
static xmlSecKeyDataKlass xmlSecOpenSSLKeyData ## klassName ## Klass = {                                    \
942
    sizeof(xmlSecKeyDataKlass),                 /* xmlSecSize klassSize */                                  \
943
    xmlSecOpenSSLEvpKeyDataSize,                /* xmlSecSize objSize */                                    \
944
                                                                                                            \
945
    /* data */                                                                                              \
946
    keyName,                                    /* const xmlChar* name; */                                  \
947
    usage,                                      /* xmlSecKeyDataUsage usage; */                             \
948
    keyHref,                                    /* const xmlChar* href; */                                  \
949
    dataNodeName,                               /* const xmlChar* dataNodeName; */                          \
950
    dataNodeNs,                                 /* const xmlChar* dataNodeNs; */                            \
951
                                                                                                            \
952
    /* constructors/destructor */                                                                           \
953
    xmlSecOpenSSLEvpKeyDataInitialize,          /* xmlSecKeyDataInitMethod initialize; */             \
954
    xmlSecOpenSSLEvpKeyDataDuplicate,           /* xmlSecKeyDataDuplicateMethod duplicate; */               \
955
    xmlSecOpenSSLEvpKeyDataFinalize,            /* xmlSecKeyDataFinalizeMethod finalize; */                 \
956
    generate,                                   /* xmlSecKeyDataGenerateMethod generate; */                 \
957
                                                                                                            \
958
    /* get info */                                                                                          \
959
    xmlSecOpenSSLEvpKeyDataGetType,             /* xmlSecKeyDataGetTypeMethod getType; */                   \
960
    xmlSecOpenSSLEvpKeyDataGetKeySize,          /* xmlSecKeyDataGetSizeMethod getSize; */                   \
961
    NULL,                                       /* DEPRECATED xmlSecKeyDataGetIdentifier getIdentifier; */  \
962
                                                                                                            \
963
    /* read/write */                                                                                        \
964
    xmlRead,                                    /* xmlSecKeyDataXmlReadMethod xmlRead; */                   \
965
    xmlWrite,                                   /* xmlSecKeyDataXmlWriteMethod xmlWrite; */                 \
966
    NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */                   \
967
    NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */                 \
968
                                                                                                            \
969
    /* debug */                                                                                             \
970
    xmlSecKeyDataDebugDumpImpl,                 /* xmlSecKeyDataDebugDumpMethod debugDump; */               \
971
    xmlSecKeyDataDebugXmlDumpImpl,              /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */            \
972
                                                                                                            \
973
    /* reserved for the future */                                                                           \
974
    NULL,                                       /* void* reserved0; */                                      \
975
    NULL,                                       /* void* reserved1; */                                      \
976
};
977
978
#define XMLSEC_OPENSSL_EVP_KEY_KLASS_EX(klassName, xmlName, usage, dataNodeName, dataNodeNs, generate, xmlRead, xmlWrite)  \
979
    XMLSEC_OPENSSL_EVP_KEY_KLASS_EX2(klassName, xmlSecName ## xmlName ## KeyValue, xmlSecHref ## xmlName ## KeyValue, usage, dataNodeName, dataNodeNs, generate, xmlRead, xmlWrite)
980
981
982
#define XMLSEC_OPENSSL_EVP_KEY_KLASS(klassName, xmlName)                                                    \
983
    XMLSEC_OPENSSL_EVP_KEY_KLASS_EX(klassName, xmlName,                                                     \
984
        xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageRetrievalMethodNodeXml,                          \
985
        NULL, NULL, NULL, NULL, NULL)
986
987
988
#ifndef XMLSEC_NO_DSA
989
/******************************************************************************
990
 *
991
 * The DSAKeyValue Element (http://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue)
992
 *
993
 *****************************************************************************/
994
0
#define XMLSEC_OPENSSL_DSA_EVP_NAME              "DSA"
995
996
/**
997
 * @brief Holds the parts of OpenSSL DSA key.
998
 */
999
typedef struct _xmlSecOpenSSLKeyValueDsa {
1000
    BIGNUM* p;
1001
    BIGNUM* q;
1002
    BIGNUM* g;
1003
    BIGNUM* pub_key;
1004
    BIGNUM* priv_key;
1005
    int notOwner;
1006
} xmlSecOpenSSLKeyValueDsa, *xmlSecOpenSSLKeyValueDsaPtr;
1007
1008
static int
1009
0
xmlSecOpenSSLKeyValueDsaInitialize(xmlSecOpenSSLKeyValueDsaPtr dsaKeyValue) {
1010
0
    xmlSecAssert2(dsaKeyValue != NULL, -1);
1011
0
    memset(dsaKeyValue, 0, sizeof(*dsaKeyValue));
1012
0
    return(0);
1013
0
}
1014
1015
static void
1016
0
xmlSecOpenSSLKeyValueDsaFinalize(xmlSecOpenSSLKeyValueDsaPtr dsaKeyValue) {
1017
0
    xmlSecAssert(dsaKeyValue != NULL);
1018
1019
0
    if((dsaKeyValue->notOwner == 0) && (dsaKeyValue->p != NULL)) {
1020
0
        BN_clear_free(dsaKeyValue->p);
1021
0
    }
1022
0
    if((dsaKeyValue->notOwner == 0) && (dsaKeyValue->q != NULL)) {
1023
0
        BN_clear_free(dsaKeyValue->q);
1024
0
    }
1025
0
    if((dsaKeyValue->notOwner == 0) && (dsaKeyValue->g != NULL)) {
1026
0
        BN_clear_free(dsaKeyValue->g);
1027
0
    }
1028
0
    if((dsaKeyValue->notOwner == 0) && (dsaKeyValue->pub_key != NULL)) {
1029
0
        BN_clear_free(dsaKeyValue->pub_key);
1030
0
    }
1031
0
    if((dsaKeyValue->notOwner == 0) && (dsaKeyValue->priv_key != NULL)) {
1032
0
        BN_clear_free(dsaKeyValue->priv_key);
1033
0
    }
1034
0
    OPENSSL_cleanse(dsaKeyValue, sizeof(*dsaKeyValue));
1035
0
}
1036
1037
1038
static int              xmlSecOpenSSLKeyDataDsaXmlRead          (xmlSecKeyDataId id,
1039
                                                                 xmlSecKeyPtr key,
1040
                                                                 xmlNodePtr node,
1041
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
1042
static int              xmlSecOpenSSLKeyDataDsaXmlWrite         (xmlSecKeyDataId id,
1043
                                                                 xmlSecKeyPtr key,
1044
                                                                 xmlNodePtr node,
1045
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
1046
static int              xmlSecOpenSSLKeyDataDsaGenerate         (xmlSecKeyDataPtr data,
1047
                                                                 xmlSecSize sizeBits,
1048
                                                                 xmlSecKeyDataType type);
1049
1050
1051
static xmlSecKeyDataPtr xmlSecOpenSSLKeyDataDsaRead             (xmlSecKeyDataId id,
1052
                                                                 xmlSecKeyValueDsaPtr dsaValue);
1053
static int              xmlSecOpenSSLKeyDataDsaWrite            (xmlSecKeyDataId id,
1054
                                                                 xmlSecKeyDataPtr data,
1055
                                                                 xmlSecKeyValueDsaPtr dsaValue,
1056
                                                                 int writePrivateKey);
1057
1058
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX(Dsa, DSA,
1059
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
1060
    xmlSecNodeDSAKeyValue, xmlSecDSigNs,
1061
    xmlSecOpenSSLKeyDataDsaGenerate,
1062
    xmlSecOpenSSLKeyDataDsaXmlRead,
1063
    xmlSecOpenSSLKeyDataDsaXmlWrite)
1064
1065
/**
1066
 * @brief The DSA key data klass.
1067
 * @return pointer to DSA key data klass.
1068
 */
1069
xmlSecKeyDataId
1070
1.45k
xmlSecOpenSSLKeyDataDsaGetKlass(void) {
1071
1.45k
    return(&xmlSecOpenSSLKeyDataDsaKlass);
1072
1.45k
}
1073
1074
/**
1075
 * @brief Sets the DSA key data value to OpenSSL EVP key.
1076
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
1077
 * @param data the pointer to DSA key data.
1078
 * @param pKey the pointer to OpenSSL EVP key.
1079
 * @return 0 on success or a negative value otherwise.
1080
 */
1081
int
1082
0
xmlSecOpenSSLKeyDataDsaAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
1083
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1084
0
    xmlSecAssert2(pKey != NULL, -1);
1085
0
    xmlSecAssert2(EVP_PKEY_base_id(pKey) == EVP_PKEY_DSA, -1);
1086
1087
0
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
1088
0
}
1089
1090
/**
1091
 * @brief Gets the OpenSSL EVP key from DSA key data.
1092
 * @param data the pointer to DSA key data.
1093
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
1094
 */
1095
EVP_PKEY*
1096
0
xmlSecOpenSSLKeyDataDsaGetEvp(xmlSecKeyDataPtr data) {
1097
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), NULL);
1098
1099
0
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
1100
0
}
1101
1102
1103
static int
1104
xmlSecOpenSSLKeyDataDsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
1105
0
                               xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1106
1107
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDsaId, -1);
1108
0
    return(xmlSecKeyDataDsaXmlRead(id, key, node, keyInfoCtx,
1109
0
        xmlSecOpenSSLKeyDataDsaRead));
1110
0
}
1111
1112
static int
1113
xmlSecOpenSSLKeyDataDsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
1114
0
                                xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1115
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDsaId, -1);
1116
0
    return(xmlSecKeyDataDsaXmlWrite(id, key, node, keyInfoCtx,
1117
0
        xmlSecBase64GetDefaultLineSize(), 1, /* add line breaks */
1118
0
        xmlSecOpenSSLKeyDataDsaWrite));
1119
0
}
1120
1121
#if !defined(XMLSEC_OPENSSL_API_111)
1122
1123
static int
1124
0
xmlSecOpenSSLKeyDataDsaGetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDsaPtr dsaKeyValue) {
1125
0
    const EVP_PKEY* pKey = NULL;
1126
0
    int ret;
1127
1128
0
    xmlSecAssert2(data != NULL, -1);
1129
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1130
0
    xmlSecAssert2(dsaKeyValue != NULL, -1);
1131
1132
0
    pKey = xmlSecOpenSSLKeyDataDsaGetEvp(data);
1133
0
    xmlSecAssert2(pKey != NULL, -1);
1134
1135
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_P, &(dsaKeyValue->p));
1136
0
    if((ret != 1) || (dsaKeyValue->p == NULL)) {
1137
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(p)", xmlSecKeyDataGetName(data));
1138
0
        return(-1);
1139
0
    }
1140
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_Q, &(dsaKeyValue->q));
1141
0
    if((ret != 1) || (dsaKeyValue->q == NULL)) {
1142
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(q)", xmlSecKeyDataGetName(data));
1143
0
        return(-1);
1144
0
    }
1145
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_G, &(dsaKeyValue->g));
1146
0
    if((ret != 1) || (dsaKeyValue->g == NULL)) {
1147
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(g)", xmlSecKeyDataGetName(data));
1148
0
        return(-1);
1149
0
    }
1150
1151
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_PUB_KEY, &(dsaKeyValue->pub_key));
1152
0
    if((ret != 1) || (dsaKeyValue->pub_key == NULL)) {
1153
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(pub_key)", xmlSecKeyDataGetName(data));
1154
0
        return(-1);
1155
0
    }
1156
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_PRIV_KEY, &(dsaKeyValue->priv_key));
1157
0
    if((ret != 1) || (dsaKeyValue->priv_key == NULL)) {
1158
        /* ignore the error -- public key doesn't have private component */
1159
0
    }
1160
1161
    /* success */
1162
0
    return(0);
1163
0
}
1164
1165
static int
1166
0
xmlSecOpenSSLKeyDataDsaSetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDsaPtr dsaKeyValue) {
1167
0
    EVP_PKEY* pKey = NULL;
1168
0
    EVP_PKEY_CTX* ctx = NULL;
1169
0
    OSSL_PARAM_BLD* param_bld = NULL;
1170
0
    OSSL_PARAM* params = NULL;
1171
0
    int ret;
1172
0
    int res = -1;
1173
1174
0
    xmlSecAssert2(data != NULL, -1);
1175
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1176
0
    xmlSecAssert2(dsaKeyValue != NULL, -1);
1177
0
    xmlSecAssert2(dsaKeyValue->p != NULL, -1);
1178
0
    xmlSecAssert2(dsaKeyValue->q != NULL, -1);
1179
0
    xmlSecAssert2(dsaKeyValue->g != NULL, -1);
1180
0
    xmlSecAssert2(dsaKeyValue->pub_key != NULL, -1);
1181
1182
0
    param_bld = OSSL_PARAM_BLD_new();
1183
0
    if(param_bld == NULL) {
1184
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_new",
1185
0
            xmlSecKeyDataGetName(data));
1186
0
        goto done;
1187
0
    }
1188
0
    ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, dsaKeyValue->p);
1189
0
    if(ret != 1) {
1190
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(p)",
1191
0
            xmlSecKeyDataGetName(data));
1192
0
        goto done;
1193
0
    }
1194
0
    ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, dsaKeyValue->q);
1195
0
    if(ret != 1) {
1196
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(q)",
1197
0
            xmlSecKeyDataGetName(data));
1198
0
        goto done;
1199
0
    }
1200
0
    ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, dsaKeyValue->g);
1201
0
    if(ret != 1) {
1202
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(g)",
1203
0
            xmlSecKeyDataGetName(data));
1204
0
        goto done;
1205
0
    }
1206
0
    ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, dsaKeyValue->pub_key);
1207
0
    if(ret != 1) {
1208
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(pub_key)",
1209
0
            xmlSecKeyDataGetName(data));
1210
0
        goto done;
1211
0
    }
1212
0
    if(dsaKeyValue->priv_key != NULL) {
1213
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, dsaKeyValue->priv_key);
1214
0
        if(ret != 1) {
1215
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(priv_key)",
1216
0
                xmlSecKeyDataGetName(data));
1217
0
            goto done;
1218
0
        }
1219
0
    }
1220
1221
0
    params = OSSL_PARAM_BLD_to_param(param_bld);
1222
0
    if(params == NULL) {
1223
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_to_param",
1224
0
            xmlSecKeyDataGetName(data));
1225
0
        goto done;
1226
0
    }
1227
0
    ctx = EVP_PKEY_CTX_new_from_name(xmlSecOpenSSLGetLibCtx(), XMLSEC_OPENSSL_DSA_EVP_NAME, NULL);
1228
0
    if(ctx == NULL) {
1229
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_name",
1230
0
            xmlSecKeyDataGetName(data));
1231
0
        goto done;
1232
0
    }
1233
1234
0
    ret = EVP_PKEY_fromdata_init(ctx);
1235
0
    if(ret <= 0) {
1236
0
        xmlSecOpenSSLError("EVP_PKEY_fromdata_init",
1237
0
            xmlSecKeyDataGetName(data));
1238
0
        goto done;
1239
0
    }
1240
    /*
1241
     * If the private key is not present, import only the public key.
1242
     * Importing a keypair with an empty private key parameter fails.
1243
     */
1244
0
    ret = EVP_PKEY_fromdata(ctx, &pKey, (dsaKeyValue->priv_key != NULL) ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY, params);
1245
0
    if(ret <= 0) {
1246
0
        xmlSecOpenSSLError("EVP_PKEY_fromdata", xmlSecKeyDataGetName(data));
1247
0
        goto done;
1248
0
    }
1249
0
    ret = xmlSecOpenSSLKeyDataDsaAdoptEvp(data, pKey);
1250
0
    if(ret < 0) {
1251
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaAdoptEvp", xmlSecKeyDataGetName(data));
1252
0
        goto done;
1253
0
    }
1254
0
    pKey = NULL;
1255
1256
    /* success */
1257
0
    res = 0;
1258
1259
0
done:
1260
0
    if(pKey != NULL) {
1261
0
        EVP_PKEY_free(pKey);
1262
0
    }
1263
0
    if(ctx != NULL) {
1264
0
        EVP_PKEY_CTX_free(ctx);
1265
0
    }
1266
0
    if(params != NULL) {
1267
0
        OSSL_PARAM_free(params);
1268
0
    }
1269
0
    if(param_bld != NULL) {
1270
0
        OSSL_PARAM_BLD_free(param_bld);
1271
0
    }
1272
0
    return(res);
1273
0
}
1274
1275
static int
1276
0
xmlSecOpenSSLKeyDataDsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type XMLSEC_ATTRIBUTE_UNUSED) {
1277
0
    EVP_PKEY_CTX* pctx = NULL;
1278
0
    EVP_PKEY_CTX* kctx = NULL;
1279
0
    OSSL_PARAM_BLD* param_bld = NULL;
1280
0
    OSSL_PARAM* params = NULL;
1281
0
    EVP_PKEY* params_pKey = NULL;
1282
0
    EVP_PKEY* pKey = NULL;
1283
0
    int ret;
1284
0
    int res = -1;
1285
1286
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1287
0
    xmlSecAssert2(sizeBits > 0, -1);
1288
0
    XMLSEC_UNREFERENCED(type);
1289
1290
    /* step 1: generate DSA parameters (p, q, g) */
1291
0
    pctx = EVP_PKEY_CTX_new_from_name(xmlSecOpenSSLGetLibCtx(), XMLSEC_OPENSSL_DSA_EVP_NAME, NULL);
1292
0
    if(pctx == NULL) {
1293
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_name", xmlSecKeyDataGetName(data));
1294
0
        goto done;
1295
0
    }
1296
0
    ret = EVP_PKEY_paramgen_init(pctx);
1297
0
    if(ret <= 0) {
1298
0
        xmlSecOpenSSLError("EVP_PKEY_paramgen_init", xmlSecKeyDataGetName(data));
1299
0
        goto done;
1300
0
    }
1301
0
    param_bld = OSSL_PARAM_BLD_new();
1302
0
    if(param_bld == NULL) {
1303
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_new", xmlSecKeyDataGetName(data));
1304
0
        goto done;
1305
0
    }
1306
0
    if(OSSL_PARAM_BLD_push_size_t(param_bld, OSSL_PKEY_PARAM_BITS, sizeBits) != 1) {
1307
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_size_t(bits)", xmlSecKeyDataGetName(data));
1308
0
        goto done;
1309
0
    }
1310
0
    params = OSSL_PARAM_BLD_to_param(param_bld);
1311
0
    if(params == NULL) {
1312
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_to_param", xmlSecKeyDataGetName(data));
1313
0
        goto done;
1314
0
    }
1315
0
    ret = EVP_PKEY_CTX_set_params(pctx, params);
1316
0
    if(ret <= 0) {
1317
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_set_params", xmlSecKeyDataGetName(data));
1318
0
        goto done;
1319
0
    }
1320
0
    ret = EVP_PKEY_generate(pctx, &params_pKey);
1321
0
    if(ret <= 0) {
1322
0
        xmlSecOpenSSLError2("EVP_PKEY_generate(params)", xmlSecKeyDataGetName(data),
1323
0
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
1324
0
        goto done;
1325
0
    }
1326
1327
    /* step 2: generate the key pair from the DSA parameters */
1328
0
    kctx = EVP_PKEY_CTX_new_from_pkey(xmlSecOpenSSLGetLibCtx(), params_pKey, NULL);
1329
0
    if(kctx == NULL) {
1330
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_pkey", xmlSecKeyDataGetName(data));
1331
0
        goto done;
1332
0
    }
1333
0
    ret = EVP_PKEY_keygen_init(kctx);
1334
0
    if(ret <= 0) {
1335
0
        xmlSecOpenSSLError("EVP_PKEY_keygen_init", xmlSecKeyDataGetName(data));
1336
0
        goto done;
1337
0
    }
1338
0
    ret = EVP_PKEY_generate(kctx, &pKey);
1339
0
    if(ret <= 0) {
1340
0
        xmlSecOpenSSLError2("EVP_PKEY_generate(key)", xmlSecKeyDataGetName(data),
1341
0
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
1342
0
        goto done;
1343
0
    }
1344
0
    ret = xmlSecOpenSSLKeyDataDsaAdoptEvp(data, pKey);
1345
0
    if(ret < 0) {
1346
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaAdoptEvp", xmlSecKeyDataGetName(data));
1347
0
        goto done;
1348
0
    }
1349
0
    pKey = NULL;
1350
1351
    /* success */
1352
0
    res = 0;
1353
1354
0
done:
1355
0
    if(pKey != NULL) {
1356
0
        EVP_PKEY_free(pKey);
1357
0
    }
1358
0
    if(params_pKey != NULL) {
1359
0
        EVP_PKEY_free(params_pKey);
1360
0
    }
1361
0
    if(params != NULL) {
1362
0
        OSSL_PARAM_free(params);
1363
0
    }
1364
0
    if(param_bld != NULL) {
1365
0
        OSSL_PARAM_BLD_free(param_bld);
1366
0
    }
1367
0
    if(kctx != NULL) {
1368
0
        EVP_PKEY_CTX_free(kctx);
1369
0
    }
1370
0
    if(pctx != NULL) {
1371
0
        EVP_PKEY_CTX_free(pctx);
1372
0
    }
1373
1374
0
    return(res);
1375
0
}
1376
1377
#else /* !defined(XMLSEC_OPENSSL_API_111) */
1378
1379
/* on success, the ownership of @p dsa is transferred to @p data,
1380
 * on error, the caller is still responsible for destroying it
1381
 */
1382
static int
1383
xmlSecOpenSSLKeyDataDsaAdoptDsa(xmlSecKeyDataPtr data, DSA* dsa) {
1384
    EVP_PKEY* pKey = NULL;
1385
    int ret;
1386
1387
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1388
    xmlSecAssert2(dsa != NULL, -1);
1389
1390
    /* construct new EVP_PKEY */
1391
    pKey = EVP_PKEY_new();
1392
    if(pKey == NULL) {
1393
        xmlSecOpenSSLError("EVP_PKEY_new", xmlSecKeyDataGetName(data));
1394
        return(-1);
1395
    }
1396
1397
    ret = EVP_PKEY_assign_DSA(pKey, dsa);
1398
    if(ret != 1) {
1399
        xmlSecOpenSSLError("EVP_PKEY_assign_DSA", xmlSecKeyDataGetName(data));
1400
        EVP_PKEY_free(pKey);
1401
        return(-1);
1402
    }
1403
    /* pKey owns dsa now */
1404
1405
    ret = xmlSecOpenSSLKeyDataDsaAdoptEvp(data, pKey);
1406
    if(ret < 0) {
1407
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaAdoptEvp", xmlSecKeyDataGetName(data));
1408
        DSA_up_ref(dsa); /* give dsa back to the caller (ignore return value) */
1409
        EVP_PKEY_free(pKey);
1410
        return(-1);
1411
    }
1412
    /* data owns pKey now */
1413
1414
    /* success: data->pKey owns dsa now */
1415
    return(0);
1416
}
1417
1418
static DSA*
1419
xmlSecOpenSSLKeyDataDsaGetDsa(xmlSecKeyDataPtr data) {
1420
    EVP_PKEY* pKey;
1421
1422
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), NULL);
1423
1424
    pKey = xmlSecOpenSSLKeyDataDsaGetEvp(data);
1425
    xmlSecAssert2((pKey == NULL) || (EVP_PKEY_base_id(pKey) == EVP_PKEY_DSA), NULL);
1426
1427
    return((pKey != NULL) ? EVP_PKEY_get0_DSA(pKey) : NULL);
1428
}
1429
1430
static int
1431
xmlSecOpenSSLKeyDataDsaGetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDsaPtr dsaKeyValue) {
1432
    DSA* dsa = NULL;
1433
1434
    xmlSecAssert2(data != NULL, -1);
1435
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1436
    xmlSecAssert2(dsaKeyValue != NULL, -1);
1437
1438
    /* ensure the values are not getting free'd */
1439
    dsaKeyValue->notOwner = 1;
1440
1441
    dsa = xmlSecOpenSSLKeyDataDsaGetDsa(data);
1442
    if(dsa == NULL) {
1443
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaGetDsa", xmlSecKeyDataGetName(data));
1444
        return(-1);
1445
    }
1446
    DSA_get0_pqg(dsa,
1447
        (const BIGNUM**)&(dsaKeyValue->p),
1448
        (const BIGNUM**)&(dsaKeyValue->q),
1449
        (const BIGNUM**)&(dsaKeyValue->g));
1450
    if((dsaKeyValue->p == NULL) || (dsaKeyValue->q == NULL) || (dsaKeyValue->g == NULL)) {
1451
        xmlSecOpenSSLError("DSA_get0_pqg", xmlSecKeyDataGetName(data));
1452
        return(-1);
1453
    }
1454
    DSA_get0_key(dsa,
1455
        (const BIGNUM**)&(dsaKeyValue->pub_key),
1456
        (const BIGNUM**)&(dsaKeyValue->priv_key));
1457
    if(dsaKeyValue->pub_key == NULL) {
1458
        xmlSecOpenSSLError("DSA_get0_key", xmlSecKeyDataGetName(data));
1459
        return(-1);
1460
    }
1461
1462
    /* success */
1463
    return(0);
1464
}
1465
1466
1467
static int
1468
xmlSecOpenSSLKeyDataDsaSetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDsaPtr dsaKeyValue) {
1469
    DSA* dsa = NULL;
1470
    int ret;
1471
    int res = -1;
1472
1473
    xmlSecAssert2(data != NULL, -1);
1474
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1475
    xmlSecAssert2(dsaKeyValue != NULL, -1);
1476
    xmlSecAssert2(dsaKeyValue->p != NULL, -1);
1477
    xmlSecAssert2(dsaKeyValue->q != NULL, -1);
1478
    xmlSecAssert2(dsaKeyValue->g != NULL, -1);
1479
    xmlSecAssert2(dsaKeyValue->pub_key != NULL, -1);
1480
1481
    dsa = DSA_new();
1482
    if(dsa == NULL) {
1483
        xmlSecOpenSSLError("DSA_new", xmlSecKeyDataGetName(data));
1484
        goto done;
1485
    }
1486
1487
    ret = DSA_set0_pqg(dsa, dsaKeyValue->p, dsaKeyValue->q, dsaKeyValue->g);
1488
    if(ret != 1) {
1489
        xmlSecOpenSSLError("DSA_set0_pqg", xmlSecKeyDataGetName(data));
1490
        goto done;
1491
    }
1492
    dsaKeyValue->p = NULL;
1493
    dsaKeyValue->q = NULL;
1494
    dsaKeyValue->g = NULL;
1495
1496
    ret = DSA_set0_key(dsa, dsaKeyValue->pub_key, dsaKeyValue->priv_key);
1497
    if(ret != 1) {
1498
        xmlSecOpenSSLError("DSA_set0_key", xmlSecKeyDataGetName(data));
1499
        goto done;
1500
    }
1501
    dsaKeyValue->pub_key = NULL;
1502
    dsaKeyValue->priv_key = NULL;
1503
1504
    ret = xmlSecOpenSSLKeyDataDsaAdoptDsa(data, dsa);
1505
    if(ret < 0) {
1506
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaAdoptDsa", xmlSecKeyDataGetName(data));
1507
        goto done;
1508
    }
1509
    dsa = NULL;  /* ownership transferred to AdoptDsa */
1510
1511
    /* success */
1512
    res = 0;
1513
1514
done:
1515
    /* cleanup */
1516
    if(dsa != NULL) {
1517
        DSA_free(dsa);
1518
    }
1519
    return(res);
1520
}
1521
1522
static int
1523
xmlSecOpenSSLKeyDataDsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type XMLSEC_ATTRIBUTE_UNUSED) {
1524
    DSA* dsa = NULL;
1525
    int counter_ret, bitsLen;
1526
    unsigned long h_ret;
1527
    int ret;
1528
    int res = -1;
1529
1530
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1531
    xmlSecAssert2(sizeBits > 0, -1);
1532
    XMLSEC_UNREFERENCED(type);
1533
1534
    dsa = DSA_new();
1535
    if(dsa == NULL) {
1536
        xmlSecOpenSSLError("DSA_new",
1537
                           xmlSecKeyDataGetName(data));
1538
        goto done;
1539
    }
1540
1541
    XMLSEC_SAFE_CAST_SIZE_TO_INT(sizeBits, bitsLen, goto done, NULL);
1542
    ret = DSA_generate_parameters_ex(dsa, bitsLen, NULL, 0, &counter_ret, &h_ret, NULL);
1543
    if(ret != 1) {
1544
        xmlSecOpenSSLError2("DSA_generate_parameters_ex",  xmlSecKeyDataGetName(data),
1545
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
1546
        goto done;
1547
    }
1548
1549
    ret = DSA_generate_key(dsa);
1550
    if(ret != 1) {
1551
        xmlSecOpenSSLError("DSA_generate_key", xmlSecKeyDataGetName(data));
1552
        goto done;
1553
    }
1554
1555
    ret = xmlSecOpenSSLKeyDataDsaAdoptDsa(data, dsa);
1556
    if(ret < 0) {
1557
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaAdoptDsa", xmlSecKeyDataGetName(data));
1558
        goto done;
1559
    }
1560
    dsa = NULL;  /* ownership transferred to AdoptDsa */
1561
1562
    /* success */
1563
    res = 0;
1564
1565
done:
1566
    if(dsa != NULL) {
1567
        DSA_free(dsa);
1568
    }
1569
    return(res);
1570
}
1571
1572
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
1573
1574
static xmlSecKeyDataPtr
1575
0
xmlSecOpenSSLKeyDataDsaRead(xmlSecKeyDataId id, xmlSecKeyValueDsaPtr dsaValue) {
1576
0
    xmlSecKeyDataPtr data = NULL;
1577
0
    xmlSecKeyDataPtr res = NULL;
1578
0
    xmlSecOpenSSLKeyValueDsa dsaKeyValue;
1579
0
    int ret;
1580
1581
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDsaId, NULL);
1582
0
    xmlSecAssert2(dsaValue != NULL, NULL);
1583
1584
0
    ret = xmlSecOpenSSLKeyValueDsaInitialize(&dsaKeyValue);
1585
0
    if(ret < 0) {
1586
0
        xmlSecInternalError("xmlSecOpenSSLKeyValueDsaInitialize",
1587
0
            xmlSecKeyDataKlassGetName(id));
1588
0
        goto done;
1589
0
    }
1590
1591
    /* p */
1592
0
    ret = xmlSecOpenSSLGetBNValue(&(dsaValue->p), &(dsaKeyValue.p));
1593
0
    if(ret < 0) {
1594
0
        xmlSecInternalError("xmlSecOpenSSLGetBNValue(p)",
1595
0
            xmlSecKeyDataKlassGetName(id));
1596
0
        goto done;
1597
0
    }
1598
    /* q */
1599
0
    ret = xmlSecOpenSSLGetBNValue(&(dsaValue->q), &(dsaKeyValue.q));
1600
0
    if(ret < 0) {
1601
0
        xmlSecInternalError("xmlSecOpenSSLGetBNValue(q)",
1602
0
            xmlSecKeyDataKlassGetName(id));
1603
0
        goto done;
1604
0
    }
1605
    /* g */
1606
0
    ret = xmlSecOpenSSLGetBNValue(&(dsaValue->g), &(dsaKeyValue.g));
1607
0
    if(ret < 0) {
1608
0
        xmlSecInternalError("xmlSecOpenSSLGetBNValue(g)",
1609
0
            xmlSecKeyDataKlassGetName(id));
1610
0
        goto done;
1611
0
    }
1612
    /* y */
1613
0
    ret = xmlSecOpenSSLGetBNValue(&(dsaValue->y), &(dsaKeyValue.pub_key));
1614
0
    if(ret < 0) {
1615
0
        xmlSecInternalError("xmlSecOpenSSLGetBNValue(y)",
1616
0
            xmlSecKeyDataKlassGetName(id));
1617
0
        goto done;
1618
0
    }
1619
    /* x (only for private key) */
1620
0
    if(xmlSecBufferGetSize(&(dsaValue->x)) > 0) {
1621
        /* x */
1622
0
        ret = xmlSecOpenSSLGetBNValue(&(dsaValue->x), &(dsaKeyValue.priv_key));
1623
0
        if(ret < 0) {
1624
0
            xmlSecInternalError("xmlSecOpenSSLGetBNValue(x)",
1625
0
                xmlSecKeyDataKlassGetName(id));
1626
0
            goto done;
1627
0
        }
1628
0
    }
1629
1630
0
    data = xmlSecKeyDataCreate(id);
1631
0
    if(data == NULL) {
1632
0
        xmlSecInternalError("xmlSecKeyDataCreate",
1633
0
            xmlSecKeyDataKlassGetName(id));
1634
0
        goto done;
1635
0
    }
1636
1637
0
    ret = xmlSecOpenSSLKeyDataDsaSetValue(data, &dsaKeyValue);
1638
0
    if(ret < 0) {
1639
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaSetValue",
1640
0
            xmlSecKeyDataKlassGetName(id));
1641
0
        goto done;
1642
0
    }
1643
1644
    /* success */
1645
0
    res = data;
1646
0
    data = NULL;
1647
1648
0
done:
1649
0
    if(data != NULL) {
1650
0
        xmlSecKeyDataDestroy(data);
1651
0
    }
1652
0
    xmlSecOpenSSLKeyValueDsaFinalize(&dsaKeyValue);
1653
0
    return(res);
1654
0
}
1655
1656
static int
1657
xmlSecOpenSSLKeyDataDsaWrite(xmlSecKeyDataId id, xmlSecKeyDataPtr data,
1658
0
                             xmlSecKeyValueDsaPtr dsaValue, int writePrivateKey) {
1659
0
    xmlSecOpenSSLKeyValueDsa dsaKeyValue;
1660
0
    int ret;
1661
0
    int res = -1;
1662
1663
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDsaId, -1);
1664
0
    xmlSecAssert2(data != NULL, -1);
1665
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDsaId), -1);
1666
0
    xmlSecAssert2(dsaValue != NULL, -1);
1667
1668
    /* first, get all values */
1669
0
    ret = xmlSecOpenSSLKeyValueDsaInitialize(&dsaKeyValue);
1670
0
    if(ret < 0) {
1671
0
        xmlSecInternalError("xmlSecOpenSSLKeyValueDsaInitialize",
1672
0
            xmlSecKeyDataGetName(data));
1673
0
        goto done;
1674
0
    }
1675
1676
0
    ret = xmlSecOpenSSLKeyDataDsaGetValue(data, &dsaKeyValue);
1677
0
    if(ret < 0) {
1678
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDsaGetValue",
1679
0
            xmlSecKeyDataGetName(data));
1680
0
        goto done;
1681
0
    }
1682
1683
    /* p */
1684
0
    xmlSecAssert2(dsaKeyValue.p != NULL, -1);
1685
0
    ret = xmlSecOpenSSLSetBNValue(dsaKeyValue.p, &(dsaValue->p));
1686
0
    if(ret < 0) {
1687
0
        xmlSecInternalError("xmlSecOpenSSLSetBNValue(p)",
1688
0
            xmlSecKeyDataKlassGetName(id));
1689
0
        goto done;
1690
0
    }
1691
1692
    /* q */
1693
0
    xmlSecAssert2(dsaKeyValue.q != NULL, -1);
1694
0
    ret = xmlSecOpenSSLSetBNValue(dsaKeyValue.q, &(dsaValue->q));
1695
0
    if(ret < 0) {
1696
0
        xmlSecInternalError("xmlSecOpenSSLSetBNValue(q)",
1697
0
            xmlSecKeyDataKlassGetName(id));
1698
0
        goto done;
1699
0
    }
1700
1701
    /* g */
1702
0
    xmlSecAssert2(dsaKeyValue.g != NULL, -1);
1703
0
    ret = xmlSecOpenSSLSetBNValue(dsaKeyValue.g, &(dsaValue->g));
1704
0
    if(ret < 0) {
1705
0
        xmlSecInternalError("xmlSecOpenSSLSetBNValue(g)",
1706
0
            xmlSecKeyDataKlassGetName(id));
1707
0
        goto done;
1708
0
    }
1709
1710
    /* y */
1711
0
    xmlSecAssert2(dsaKeyValue.pub_key != NULL, -1);
1712
0
    ret = xmlSecOpenSSLSetBNValue(dsaKeyValue.pub_key, &(dsaValue->y));
1713
0
    if(ret < 0) {
1714
0
        xmlSecInternalError("xmlSecOpenSSLSetBNValue(y)",
1715
0
            xmlSecKeyDataKlassGetName(id));
1716
0
        goto done;
1717
0
    }
1718
1719
    /* x (only if available and requested) */
1720
0
    if((writePrivateKey != 0) && (dsaKeyValue.priv_key != NULL)) {
1721
0
        ret = xmlSecOpenSSLSetBNValue(dsaKeyValue.priv_key, &(dsaValue->x));
1722
0
        if(ret < 0) {
1723
0
            xmlSecInternalError("xmlSecOpenSSLSetBNValue(x)",
1724
0
                xmlSecKeyDataKlassGetName(id));
1725
0
            goto done;
1726
0
        }
1727
0
    }
1728
1729
    /* success */
1730
0
    res = 0;
1731
1732
0
done:
1733
0
    xmlSecOpenSSLKeyValueDsaFinalize(&dsaKeyValue);
1734
0
    return(res);
1735
0
}
1736
1737
#endif /* XMLSEC_NO_DSA */
1738
1739
1740
#ifndef XMLSEC_NO_DH
1741
1742
/******************************************************************************
1743
 *
1744
 * <xenc11:DHKeyValue> processing
1745
 *
1746
 *
1747
 *****************************************************************************/
1748
1749
/**
1750
 * @brief Holds the parts of OpenSSL DH key.
1751
 */
1752
typedef struct _xmlSecOpenSSLKeyValueDh {
1753
    BIGNUM* p;
1754
    BIGNUM* q;
1755
    BIGNUM* generator;
1756
    BIGNUM* pub;
1757
    BIGNUM* priv;
1758
    BIGNUM* seed;
1759
    BIGNUM* pgenCounter;
1760
    int notOwner;
1761
} xmlSecOpenSSLKeyValueDh, *xmlSecOpenSSLKeyValueDhPtr;
1762
1763
1764
/*
1765
 * https://www.openssl.org/docs/man3.1/man7/EVP_PKEY-FFC.html
1766
 *
1767
 * The DH key type uses PKCS#3 format which saves p and g, but not the 'q' value. The DHX key
1768
 * type uses X9.42 format which saves the value of 'q' and this must be used for FIPS186-4.
1769
 * Keys in both formats are accepted; the 'DHX' name is used to create new keys because it
1770
 * supports the 'q' value.
1771
 */
1772
0
#define XMLSEC_OPENSSL_DH_EVP_NAME              "DHX"
1773
1774
static int
1775
0
xmlSecOpenSSLKeyValueDhInitialize(xmlSecOpenSSLKeyValueDhPtr dhKeyValue) {
1776
0
    xmlSecAssert2(dhKeyValue != NULL, -1);
1777
0
    memset(dhKeyValue, 0, sizeof(*dhKeyValue));
1778
0
    return(0);
1779
0
}
1780
1781
static void
1782
0
xmlSecOpenSSLKeyValueDhFinalize(xmlSecOpenSSLKeyValueDhPtr dhKeyValue) {
1783
0
    xmlSecAssert(dhKeyValue != NULL);
1784
1785
0
    if((dhKeyValue->notOwner == 0) && (dhKeyValue->p != NULL)) {
1786
0
        BN_clear_free(dhKeyValue->p);
1787
0
    }
1788
0
    if((dhKeyValue->notOwner == 0) && (dhKeyValue->q != NULL)) {
1789
0
        BN_clear_free(dhKeyValue->q);
1790
0
    }
1791
0
    if((dhKeyValue->notOwner == 0) && (dhKeyValue->generator != NULL)) {
1792
0
        BN_clear_free(dhKeyValue->generator);
1793
0
    }
1794
0
    if((dhKeyValue->notOwner == 0) && (dhKeyValue->pub != NULL)) {
1795
0
        BN_clear_free(dhKeyValue->pub);
1796
0
    }
1797
0
    if((dhKeyValue->notOwner == 0) && (dhKeyValue->priv != NULL)) {
1798
0
        BN_clear_free(dhKeyValue->priv);
1799
0
    }
1800
0
    if((dhKeyValue->notOwner == 0) && (dhKeyValue->seed != NULL)) {
1801
0
        BN_clear_free(dhKeyValue->seed);
1802
0
    }
1803
0
    if((dhKeyValue->notOwner == 0) && (dhKeyValue->pgenCounter != NULL)) {
1804
0
        BN_clear_free(dhKeyValue->pgenCounter);
1805
0
    }
1806
0
    OPENSSL_cleanse(dhKeyValue, sizeof(*dhKeyValue));
1807
0
}
1808
1809
1810
static int              xmlSecOpenSSLKeyDataDhXmlRead           (xmlSecKeyDataId id,
1811
                                                                 xmlSecKeyPtr key,
1812
                                                                 xmlNodePtr node,
1813
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
1814
static int              xmlSecOpenSSLKeyDataDhXmlWrite          (xmlSecKeyDataId id,
1815
                                                                 xmlSecKeyPtr key,
1816
                                                                 xmlNodePtr node,
1817
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
1818
static int              xmlSecOpenSSLKeyDataDhGenerate          (xmlSecKeyDataPtr data,
1819
                                                                 xmlSecSize sizeBits,
1820
                                                                 xmlSecKeyDataType type);
1821
1822
static xmlSecKeyDataPtr xmlSecOpenSSLKeyDataDhRead              (xmlSecKeyDataId id,
1823
                                                                 xmlSecKeyValueDhPtr dhValue);
1824
static int              xmlSecOpenSSLKeyDataDhWrite             (xmlSecKeyDataId id,
1825
                                                                 xmlSecKeyDataPtr data,
1826
                                                                 xmlSecKeyValueDhPtr dhValue,
1827
                                                                 int writePrivateKey);
1828
1829
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX(Dh, DH,
1830
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
1831
    xmlSecNodeDHKeyValue, xmlSecEncNs,
1832
    xmlSecOpenSSLKeyDataDhGenerate,
1833
    xmlSecOpenSSLKeyDataDhXmlRead,
1834
    xmlSecOpenSSLKeyDataDhXmlWrite)
1835
1836
/**
1837
 * @brief The DH key data klass.
1838
 * @return pointer to DH key data klass.
1839
 */
1840
xmlSecKeyDataId
1841
8
xmlSecOpenSSLKeyDataDhGetKlass(void) {
1842
8
    return(&xmlSecOpenSSLKeyDataDhKlass);
1843
8
}
1844
1845
/**
1846
 * @brief Sets the DH key data value to OpenSSL EVP key.
1847
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
1848
 * @param data the pointer to DH key data.
1849
 * @param pKey the pointer to OpenSSL EVP key.
1850
 * @return 0 on success or a negative value otherwise.
1851
 */
1852
int
1853
0
xmlSecOpenSSLKeyDataDhAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
1854
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
1855
0
    xmlSecAssert2(pKey != NULL, -1);
1856
    /*
1857
     * DH keys can have two types: EVP_PKEY_DH (PKCS#3 form, no 'q' value) and
1858
     * EVP_PKEY_DHX (X9.42 form, with 'q' value).
1859
     */
1860
0
    xmlSecAssert2((EVP_PKEY_base_id(pKey) == EVP_PKEY_DH) || (EVP_PKEY_base_id(pKey) == EVP_PKEY_DHX), -1);
1861
1862
0
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
1863
0
}
1864
1865
/**
1866
 * @brief Gets the OpenSSL EVP key from DH key data.
1867
 * @param data the pointer to DH key data.
1868
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
1869
 */
1870
EVP_PKEY*
1871
0
xmlSecOpenSSLKeyDataDhGetEvp(xmlSecKeyDataPtr data) {
1872
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), NULL);
1873
1874
0
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
1875
0
}
1876
1877
1878
static int
1879
xmlSecOpenSSLKeyDataDhXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
1880
0
                               xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1881
1882
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDhId, -1);
1883
0
    return(xmlSecKeyDataDhXmlRead(id, key, node, keyInfoCtx,
1884
0
        xmlSecOpenSSLKeyDataDhRead));
1885
0
}
1886
1887
static int
1888
xmlSecOpenSSLKeyDataDhXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
1889
0
                                xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1890
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDhId, -1);
1891
0
    return(xmlSecKeyDataDhXmlWrite(id, key, node, keyInfoCtx,
1892
0
        xmlSecBase64GetDefaultLineSize(), 1, /* add line breaks */
1893
0
        xmlSecOpenSSLKeyDataDhWrite));
1894
0
}
1895
1896
#if !defined(XMLSEC_OPENSSL_API_111)
1897
1898
static int
1899
0
xmlSecOpenSSLKeyDataDhGetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDhPtr dhKeyValue) {
1900
0
    const EVP_PKEY* pKey = NULL;
1901
0
    int ret;
1902
1903
0
    xmlSecAssert2(data != NULL, -1);
1904
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
1905
0
    xmlSecAssert2(dhKeyValue != NULL, -1);
1906
1907
0
    pKey = xmlSecOpenSSLKeyDataDhGetEvp(data);
1908
0
    xmlSecAssert2(pKey != NULL, -1);
1909
1910
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_P, &(dhKeyValue->p));
1911
0
    if((ret != 1) || (dhKeyValue->p == NULL)) {
1912
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(p)", xmlSecKeyDataGetName(data));
1913
0
        return(-1);
1914
0
    }
1915
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_Q, &(dhKeyValue->q));
1916
0
    if((ret != 1) || (dhKeyValue->q == NULL)) {
1917
        /* ignore the error since q is optional for DH keys in the PKCS#3 form */
1918
0
    }
1919
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_G, &(dhKeyValue->generator));
1920
0
    if((ret != 1) || (dhKeyValue->generator == NULL)) {
1921
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(generator)", xmlSecKeyDataGetName(data));
1922
0
        return(-1);
1923
0
    }
1924
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_PUB_KEY, &(dhKeyValue->pub));
1925
0
    if((ret != 1) || (dhKeyValue->pub == NULL)) {
1926
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(public)", xmlSecKeyDataGetName(data));
1927
0
        return(-1);
1928
0
    }
1929
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_PRIV_KEY, &(dhKeyValue->priv));
1930
0
    if((ret != 1) || (dhKeyValue->priv == NULL)) {
1931
        /* ignore the error since public keys don't have private component */
1932
0
    }
1933
1934
    /* seed and pgenCounter are optional; they are only present for DH keys
1935
     * whose domain parameters were generated from a seed (PKCS#3/X9.42) */
1936
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_SEED, &(dhKeyValue->seed));
1937
0
    if((ret != 1) || (dhKeyValue->seed == NULL)) {
1938
        /* ignore the error since seed is optional for DH keys */
1939
0
    }
1940
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_FFC_PCOUNTER, &(dhKeyValue->pgenCounter));
1941
0
    if((ret != 1) || (dhKeyValue->pgenCounter == NULL)) {
1942
        /* ignore the error since pgenCounter is optional for DH keys */
1943
0
    }
1944
1945
    /* success */
1946
0
    return(0);
1947
0
}
1948
1949
static int
1950
0
xmlSecOpenSSLKeyDataDhSetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDhPtr dhKeyValue) {
1951
0
    EVP_PKEY* pKey = NULL;
1952
0
    EVP_PKEY_CTX* ctx = NULL;
1953
0
    OSSL_PARAM_BLD* param_bld = NULL;
1954
0
    OSSL_PARAM* params = NULL;
1955
0
    int ret;
1956
0
    int res = -1;
1957
1958
0
    xmlSecAssert2(data != NULL, -1);
1959
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
1960
0
    xmlSecAssert2(dhKeyValue != NULL, -1);
1961
0
    xmlSecAssert2(dhKeyValue->pub != NULL, -1);
1962
1963
0
    param_bld = OSSL_PARAM_BLD_new();
1964
0
    if(param_bld == NULL) {
1965
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_new",
1966
0
            xmlSecKeyDataGetName(data));
1967
0
        goto done;
1968
0
    }
1969
1970
    /* only required parameter */
1971
0
    ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, dhKeyValue->pub);
1972
0
    if(ret != 1) {
1973
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(public)",
1974
0
            xmlSecKeyDataGetName(data));
1975
0
        goto done;
1976
0
    }
1977
0
    if(dhKeyValue->p != NULL) {
1978
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, dhKeyValue->p);
1979
0
        if(ret != 1) {
1980
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(p)",
1981
0
                xmlSecKeyDataGetName(data));
1982
0
            goto done;
1983
0
        }
1984
0
    }
1985
0
    if(dhKeyValue->q != NULL) {
1986
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, dhKeyValue->q);
1987
0
        if(ret != 1) {
1988
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(q)",
1989
0
                xmlSecKeyDataGetName(data));
1990
0
            goto done;
1991
0
        }
1992
0
    }
1993
0
    if(dhKeyValue->generator != NULL) {
1994
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, dhKeyValue->generator);
1995
0
        if(ret != 1) {
1996
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(generator)",
1997
0
                xmlSecKeyDataGetName(data));
1998
0
            goto done;
1999
0
        }
2000
0
    }
2001
0
    if(dhKeyValue->seed != NULL) {
2002
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_SEED, dhKeyValue->seed);
2003
0
        if(ret != 1) {
2004
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(seed)",
2005
0
                xmlSecKeyDataGetName(data));
2006
0
            goto done;
2007
0
        }
2008
0
    }
2009
0
    if(dhKeyValue->pgenCounter != NULL) {
2010
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_PCOUNTER, dhKeyValue->pgenCounter);
2011
0
        if(ret != 1) {
2012
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(pgenCounter)",
2013
0
                xmlSecKeyDataGetName(data));
2014
0
            goto done;
2015
0
        }
2016
0
    }
2017
0
    if(dhKeyValue->priv != NULL) {
2018
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, dhKeyValue->priv);
2019
0
        if(ret != 1) {
2020
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(private)",
2021
0
                xmlSecKeyDataGetName(data));
2022
0
            goto done;
2023
0
        }
2024
0
    }
2025
2026
    /* create params */
2027
0
    params = OSSL_PARAM_BLD_to_param(param_bld);
2028
0
    if(params == NULL) {
2029
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_to_param",
2030
0
            xmlSecKeyDataGetName(data));
2031
0
        goto done;
2032
0
    }
2033
0
    ctx = EVP_PKEY_CTX_new_from_name(xmlSecOpenSSLGetLibCtx(), XMLSEC_OPENSSL_DH_EVP_NAME, NULL);
2034
0
    if(ctx == NULL) {
2035
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_name",
2036
0
            xmlSecKeyDataGetName(data));
2037
0
        goto done;
2038
0
    }
2039
2040
0
    ret = EVP_PKEY_fromdata_init(ctx);
2041
0
    if(ret <= 0) {
2042
0
        xmlSecOpenSSLError("EVP_PKEY_fromdata_init",
2043
0
            xmlSecKeyDataGetName(data));
2044
0
        goto done;
2045
0
    }
2046
    /*
2047
     * If the private key is not present, import only the public key.
2048
     * Importing a keypair with an empty private key parameter fails.
2049
     */
2050
0
    ret = EVP_PKEY_fromdata(ctx, &pKey, (dhKeyValue->priv != NULL) ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY, params);
2051
0
    if(ret <= 0) {
2052
0
        xmlSecOpenSSLError("EVP_PKEY_fromdata",
2053
0
            xmlSecKeyDataGetName(data));
2054
0
        goto done;
2055
0
    }
2056
0
    ret = xmlSecOpenSSLKeyDataDhAdoptEvp(data, pKey);
2057
0
    if(ret < 0) {
2058
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhAdoptEvp",
2059
0
            xmlSecKeyDataGetName(data));
2060
0
        goto done;
2061
0
    }
2062
0
    pKey = NULL;
2063
2064
    /* success */
2065
0
    res = 0;
2066
2067
0
done:
2068
0
    if(pKey != NULL) {
2069
0
        EVP_PKEY_free(pKey);
2070
0
    }
2071
0
    if(ctx != NULL) {
2072
0
        EVP_PKEY_CTX_free(ctx);
2073
0
    }
2074
0
    if(params != NULL) {
2075
0
        OSSL_PARAM_free(params);
2076
0
    }
2077
0
    if(param_bld != NULL) {
2078
0
        OSSL_PARAM_BLD_free(param_bld);
2079
0
    }
2080
0
    return(res);
2081
0
}
2082
2083
static int
2084
0
xmlSecOpenSSLKeyDataDhGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type XMLSEC_ATTRIBUTE_UNUSED) {
2085
0
    EVP_PKEY_CTX* pctx = NULL;
2086
0
    EVP_PKEY_CTX* kctx = NULL;
2087
0
    OSSL_PARAM_BLD* param_bld = NULL;
2088
0
    OSSL_PARAM* params = NULL;
2089
0
    EVP_PKEY* params_pKey = NULL;
2090
0
    EVP_PKEY* pKey = NULL;
2091
0
    int ret;
2092
0
    int res = -1;
2093
2094
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
2095
0
    xmlSecAssert2(sizeBits > 0, -1);
2096
0
    XMLSEC_UNREFERENCED(type);
2097
2098
    /* step 1: generate DH parameters (p, g) */
2099
0
    pctx = EVP_PKEY_CTX_new_from_name(xmlSecOpenSSLGetLibCtx(), XMLSEC_OPENSSL_DH_EVP_NAME, NULL);
2100
0
    if(pctx == NULL) {
2101
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_name", xmlSecKeyDataGetName(data));
2102
0
        goto done;
2103
0
    }
2104
0
    ret = EVP_PKEY_paramgen_init(pctx);
2105
0
    if(ret <= 0) {
2106
0
        xmlSecOpenSSLError("EVP_PKEY_paramgen_init", xmlSecKeyDataGetName(data));
2107
0
        goto done;
2108
0
    }
2109
2110
0
    param_bld = OSSL_PARAM_BLD_new();
2111
0
    if(param_bld == NULL) {
2112
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_new", xmlSecKeyDataGetName(data));
2113
0
        goto done;
2114
0
    }
2115
0
    ret = OSSL_PARAM_BLD_push_size_t(param_bld, OSSL_PKEY_PARAM_BITS, sizeBits);
2116
0
    if(ret != 1) {
2117
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_size_t(bits)", xmlSecKeyDataGetName(data));
2118
0
        goto done;
2119
0
    }
2120
2121
0
    params = OSSL_PARAM_BLD_to_param(param_bld);
2122
0
    if(params == NULL) {
2123
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_to_param", xmlSecKeyDataGetName(data));
2124
0
        goto done;
2125
0
    }
2126
0
    ret = EVP_PKEY_CTX_set_params(pctx, params);
2127
0
    if(ret <= 0) {
2128
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_set_params", xmlSecKeyDataGetName(data));
2129
0
        goto done;
2130
0
    }
2131
0
    ret = EVP_PKEY_generate(pctx, &params_pKey);
2132
0
    if(ret <= 0) {
2133
0
        xmlSecOpenSSLError2("EVP_PKEY_generate(params)", xmlSecKeyDataGetName(data),
2134
0
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
2135
0
        goto done;
2136
0
    }
2137
2138
    /* step 2: generate the key pair from the DH parameters */
2139
0
    kctx = EVP_PKEY_CTX_new_from_pkey(xmlSecOpenSSLGetLibCtx(), params_pKey, NULL);
2140
0
    if(kctx == NULL) {
2141
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_pkey", xmlSecKeyDataGetName(data));
2142
0
        goto done;
2143
0
    }
2144
0
    ret = EVP_PKEY_keygen_init(kctx);
2145
0
    if(ret <= 0) {
2146
0
        xmlSecOpenSSLError("EVP_PKEY_keygen_init", xmlSecKeyDataGetName(data));
2147
0
        goto done;
2148
0
    }
2149
0
    ret = EVP_PKEY_generate(kctx, &pKey);
2150
0
    if(ret <= 0) {
2151
0
        xmlSecOpenSSLError2("EVP_PKEY_generate(key)", xmlSecKeyDataGetName(data),
2152
0
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
2153
0
        goto done;
2154
0
    }
2155
0
    ret = xmlSecOpenSSLKeyDataDhAdoptEvp(data, pKey);
2156
0
    if(ret < 0) {
2157
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhAdoptEvp", xmlSecKeyDataGetName(data));
2158
0
        goto done;
2159
0
    }
2160
0
    pKey = NULL;
2161
2162
    /* success */
2163
0
    res = 0;
2164
2165
0
done:
2166
0
    if(pKey != NULL) {
2167
0
        EVP_PKEY_free(pKey);
2168
0
    }
2169
0
    if(params_pKey != NULL) {
2170
0
        EVP_PKEY_free(params_pKey);
2171
0
    }
2172
0
    if(params != NULL) {
2173
0
        OSSL_PARAM_free(params);
2174
0
    }
2175
0
    if(param_bld != NULL) {
2176
0
        OSSL_PARAM_BLD_free(param_bld);
2177
0
    }
2178
0
    if(kctx != NULL) {
2179
0
        EVP_PKEY_CTX_free(kctx);
2180
0
    }
2181
0
    if(pctx != NULL) {
2182
0
        EVP_PKEY_CTX_free(pctx);
2183
0
    }
2184
2185
0
    return(res);
2186
0
}
2187
2188
#else /* !defined(XMLSEC_OPENSSL_API_111) */
2189
2190
/* on success, the ownership of @p dh is transferred to @p data,
2191
 * on error, the caller is still responsible for destroying it
2192
 */
2193
static int
2194
xmlSecOpenSSLKeyDataDhAdoptDh(xmlSecKeyDataPtr data, DH* dh) {
2195
    EVP_PKEY* pKey = NULL;
2196
    int ret;
2197
2198
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
2199
    xmlSecAssert2(dh != NULL, -1);
2200
2201
    /* construct new EVP_PKEY */
2202
    pKey = EVP_PKEY_new();
2203
    if(pKey == NULL) {
2204
        xmlSecOpenSSLError("EVP_PKEY_new", xmlSecKeyDataGetName(data));
2205
        return(-1);
2206
    }
2207
2208
    ret = EVP_PKEY_assign_DH(pKey, dh);
2209
    if(ret != 1) {
2210
        xmlSecOpenSSLError("EVP_PKEY_assign_DH", xmlSecKeyDataGetName(data));
2211
        EVP_PKEY_free(pKey);
2212
        return(-1);
2213
    }
2214
    /* pKey owns dh now */
2215
2216
    ret = xmlSecOpenSSLKeyDataDhAdoptEvp(data, pKey);
2217
    if(ret < 0) {
2218
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhAdoptEvp", xmlSecKeyDataGetName(data));
2219
        DH_up_ref(dh); /* give dh back to the caller (ignore return value) */
2220
        EVP_PKEY_free(pKey);
2221
        return(-1);
2222
    }
2223
    /* data owns pKey now */
2224
2225
    /* success: data->pKey owns dh now */
2226
    return(0);
2227
}
2228
2229
static DH*
2230
xmlSecOpenSSLKeyDataDhGetDh(xmlSecKeyDataPtr data) {
2231
    EVP_PKEY* pKey;
2232
2233
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), NULL);
2234
2235
    pKey = xmlSecOpenSSLKeyDataDhGetEvp(data);
2236
    xmlSecAssert2((pKey == NULL) || (EVP_PKEY_base_id(pKey) == EVP_PKEY_DH) || (EVP_PKEY_base_id(pKey) == EVP_PKEY_DHX), NULL);
2237
2238
    return((pKey != NULL) ? EVP_PKEY_get0_DH(pKey) : NULL);
2239
}
2240
2241
static int
2242
xmlSecOpenSSLKeyDataDhGetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDhPtr dhKeyValue) {
2243
    DH* dh = NULL;
2244
2245
    xmlSecAssert2(data != NULL, -1);
2246
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
2247
    xmlSecAssert2(dhKeyValue != NULL, -1);
2248
2249
    /* ensure the values are not getting free'd */
2250
    dhKeyValue->notOwner = 1;
2251
2252
    dh = xmlSecOpenSSLKeyDataDhGetDh(data);
2253
    if(dh == NULL) {
2254
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhGetDh", xmlSecKeyDataGetName(data));
2255
        return(-1);
2256
    }
2257
    DH_get0_pqg(dh,
2258
        (const BIGNUM**)&(dhKeyValue->p),
2259
        (const BIGNUM**)&(dhKeyValue->q),
2260
        (const BIGNUM**)&(dhKeyValue->generator));
2261
    /* these are optional
2262
    if((dhKeyValue->p == NULL) || (dhKeyValue->q == NULL) || (dhKeyValue->generator == NULL)) {
2263
        xmlSecOpenSSLError("DH_get0_pqg", xmlSecKeyDataGetName(data));
2264
        return(-1);
2265
    }
2266
    */
2267
    DH_get0_key(dh,
2268
        (const BIGNUM**)&(dhKeyValue->pub),
2269
        (const BIGNUM**)&(dhKeyValue->priv));
2270
    if(dhKeyValue->pub == NULL) {
2271
        xmlSecOpenSSLError("DH_get0_key", xmlSecKeyDataGetName(data));
2272
        return(-1);
2273
    }
2274
2275
    /* success */
2276
    return(0);
2277
}
2278
2279
2280
static int
2281
xmlSecOpenSSLKeyDataDhSetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueDhPtr dhKeyValue) {
2282
    DH* dh = NULL;
2283
    int ret;
2284
    int res = -1;
2285
2286
    xmlSecAssert2(data != NULL, -1);
2287
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
2288
    xmlSecAssert2(dhKeyValue != NULL, -1);
2289
    xmlSecAssert2(dhKeyValue->pub != NULL, -1);
2290
2291
    dh = DH_new();
2292
    if(dh == NULL) {
2293
        xmlSecOpenSSLError("DH_new", xmlSecKeyDataGetName(data));
2294
        goto done;
2295
    }
2296
2297
    if((dhKeyValue->p != NULL) && (dhKeyValue->generator != NULL)) {
2298
        /* the subgroup order is optional; DH_set0_pqg() accepts a NULL q */
2299
        ret = DH_set0_pqg(dh, dhKeyValue->p, dhKeyValue->q, dhKeyValue->generator);
2300
        if(ret != 1) {
2301
            xmlSecOpenSSLError("DH_set0_pqg", xmlSecKeyDataGetName(data));
2302
            goto done;
2303
        }
2304
        dhKeyValue->p = NULL;
2305
        dhKeyValue->q = NULL;
2306
        dhKeyValue->generator = NULL;
2307
    }
2308
2309
    ret = DH_set0_key(dh, dhKeyValue->pub, NULL);
2310
    if(ret != 1) {
2311
        xmlSecOpenSSLError("DH_set0_key", xmlSecKeyDataGetName(data));
2312
        goto done;
2313
    }
2314
    dhKeyValue->pub = NULL;
2315
2316
    ret = xmlSecOpenSSLKeyDataDhAdoptDh(data, dh);
2317
    if(ret < 0) {
2318
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhAdoptDh", xmlSecKeyDataGetName(data));
2319
        goto done;
2320
    }
2321
    dh = NULL;  /* ownership transferred to data */
2322
2323
    /* success */
2324
    res = 0;
2325
2326
done:
2327
    /* cleanup */
2328
    if(dh != NULL) {
2329
        DH_free(dh);
2330
    }
2331
    return(res);
2332
}
2333
2334
static int
2335
xmlSecOpenSSLKeyDataDhGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type XMLSEC_ATTRIBUTE_UNUSED) {
2336
    DH* dh = NULL;
2337
    int bitsLen;
2338
    int ret;
2339
    int res = -1;
2340
2341
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
2342
    xmlSecAssert2(sizeBits > 0, -1);
2343
    XMLSEC_UNREFERENCED(type);
2344
2345
    dh = DH_new();
2346
    if(dh == NULL) {
2347
        xmlSecOpenSSLError("DH_new",
2348
                           xmlSecKeyDataGetName(data));
2349
        goto done;
2350
    }
2351
2352
    XMLSEC_SAFE_CAST_SIZE_TO_INT(sizeBits, bitsLen, goto done, NULL);
2353
    ret = DH_generate_parameters_ex(dh, bitsLen, 2, NULL); /* set generator to 2 */
2354
    if(ret != 1) {
2355
        xmlSecOpenSSLError2("DH_generate_parameters_ex",  xmlSecKeyDataGetName(data),
2356
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
2357
        goto done;
2358
    }
2359
2360
    ret = DH_generate_key(dh);
2361
    if(ret != 1) {
2362
        xmlSecOpenSSLError("DH_generate_key", xmlSecKeyDataGetName(data));
2363
        goto done;
2364
    }
2365
2366
    ret = xmlSecOpenSSLKeyDataDhAdoptDh(data, dh);
2367
    if(ret < 0) {
2368
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhAdoptDh", xmlSecKeyDataGetName(data));
2369
        goto done;
2370
    }
2371
    dh = NULL;  /* ownership transferred to data */
2372
2373
    /* success */
2374
    res = 0;
2375
2376
done:
2377
    if(dh != NULL) {
2378
        DH_free(dh);
2379
    }
2380
    return(res);
2381
}
2382
2383
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
2384
2385
2386
static xmlSecKeyDataPtr
2387
0
xmlSecOpenSSLKeyDataDhRead(xmlSecKeyDataId id, xmlSecKeyValueDhPtr dhValue) {
2388
0
    xmlSecKeyDataPtr data = NULL;
2389
0
    xmlSecKeyDataPtr res = NULL;
2390
0
    xmlSecOpenSSLKeyValueDh dhKeyValue;
2391
0
    int ret;
2392
2393
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDhId, NULL);
2394
0
    xmlSecAssert2(dhValue != NULL, NULL);
2395
2396
    /* a DH key value requires the prime and the generator; without them
2397
     * the resulting key cannot be used for key agreement */
2398
0
    if((xmlSecBufferGetSize(&(dhValue->p)) == 0) || (xmlSecBufferGetSize(&(dhValue->generator)) == 0)) {
2399
0
        xmlSecInvalidDataError("DH key value is missing the <P> or <Generator> element",
2400
0
            xmlSecKeyDataKlassGetName(id));
2401
0
        return(NULL);
2402
0
    }
2403
2404
0
    ret = xmlSecOpenSSLKeyValueDhInitialize(&dhKeyValue);
2405
0
    if(ret < 0) {
2406
0
        xmlSecInternalError("xmlSecOpenSSLKeyValueDhInitialize",
2407
0
            xmlSecKeyDataKlassGetName(id));
2408
0
        goto done;
2409
0
    }
2410
2411
    /* p: required (validated above) */
2412
0
    if (xmlSecBufferGetSize(&(dhValue->p)) > 0) {
2413
0
        ret = xmlSecOpenSSLGetBNValue(&(dhValue->p), &(dhKeyValue.p));
2414
0
        if(ret < 0) {
2415
0
            xmlSecInternalError("xmlSecOpenSSLGetBNValue(p)",
2416
0
                xmlSecKeyDataKlassGetName(id));
2417
0
            goto done;
2418
0
        }
2419
0
    }
2420
    /* q: optional */
2421
0
    if (xmlSecBufferGetSize(&(dhValue->q)) > 0) {
2422
0
        ret = xmlSecOpenSSLGetBNValue(&(dhValue->q), &(dhKeyValue.q));
2423
0
        if(ret < 0) {
2424
0
            xmlSecInternalError("xmlSecOpenSSLGetBNValue(q)",
2425
0
                xmlSecKeyDataKlassGetName(id));
2426
0
            goto done;
2427
0
        }
2428
0
    }
2429
    /* generator: required (validated above) */
2430
0
    if (xmlSecBufferGetSize(&(dhValue->generator)) > 0) {
2431
0
        ret = xmlSecOpenSSLGetBNValue(&(dhValue->generator), &(dhKeyValue.generator));
2432
0
        if(ret < 0) {
2433
0
            xmlSecInternalError("xmlSecOpenSSLGetBNValue(generator)",
2434
0
                xmlSecKeyDataKlassGetName(id));
2435
0
            goto done;
2436
0
        }
2437
0
    }
2438
    /* public: required */
2439
0
    ret = xmlSecOpenSSLGetBNValue(&(dhValue->pub), &(dhKeyValue.pub));
2440
0
    if(ret < 0) {
2441
0
        xmlSecInternalError("xmlSecOpenSSLGetBNValue(public)",
2442
0
            xmlSecKeyDataKlassGetName(id));
2443
0
        goto done;
2444
0
    }
2445
    /* seed: optional */
2446
0
    if (xmlSecBufferGetSize(&(dhValue->seed)) > 0) {
2447
0
        ret = xmlSecOpenSSLGetBNValue(&(dhValue->seed), &(dhKeyValue.seed));
2448
0
        if(ret < 0) {
2449
0
            xmlSecInternalError("xmlSecOpenSSLGetBNValue(seed)",
2450
0
                xmlSecKeyDataKlassGetName(id));
2451
0
            goto done;
2452
0
        }
2453
0
    }
2454
    /* pgenCounter: optional */
2455
0
    if (xmlSecBufferGetSize(&(dhValue->pgenCounter)) > 0) {
2456
0
        ret = xmlSecOpenSSLGetBNValue(&(dhValue->pgenCounter), &(dhKeyValue.pgenCounter));
2457
0
        if(ret < 0) {
2458
0
            xmlSecInternalError("xmlSecOpenSSLGetBNValue(pgenCounter)",
2459
0
                xmlSecKeyDataKlassGetName(id));
2460
0
            goto done;
2461
0
        }
2462
0
    }
2463
2464
0
    data = xmlSecKeyDataCreate(id);
2465
0
    if(data == NULL) {
2466
0
        xmlSecInternalError("xmlSecKeyDataCreate",
2467
0
            xmlSecKeyDataKlassGetName(id));
2468
0
        goto done;
2469
0
    }
2470
2471
0
    ret = xmlSecOpenSSLKeyDataDhSetValue(data, &dhKeyValue);
2472
0
    if(ret < 0) {
2473
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhSetValue",
2474
0
            xmlSecKeyDataKlassGetName(id));
2475
0
        goto done;
2476
0
    }
2477
2478
    /* success */
2479
0
    res = data;
2480
0
    data = NULL;
2481
2482
0
done:
2483
0
    if(data != NULL) {
2484
0
        xmlSecKeyDataDestroy(data);
2485
0
    }
2486
0
    xmlSecOpenSSLKeyValueDhFinalize(&dhKeyValue);
2487
0
    return(res);
2488
0
}
2489
2490
static int
2491
xmlSecOpenSSLKeyDataDhWrite(xmlSecKeyDataId id, xmlSecKeyDataPtr data, xmlSecKeyValueDhPtr dhValue,
2492
    int writePrivateKey XMLSEC_ATTRIBUTE_UNUSED
2493
0
) {
2494
0
    xmlSecOpenSSLKeyValueDh dhKeyValue;
2495
0
    int ret;
2496
0
    int res = -1;
2497
2498
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataDhId, -1);
2499
0
    xmlSecAssert2(data != NULL, -1);
2500
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataDhId), -1);
2501
0
    xmlSecAssert2(dhValue != NULL, -1);
2502
0
    XMLSEC_UNREFERENCED(writePrivateKey);
2503
2504
    /* first, get all values */
2505
0
    ret = xmlSecOpenSSLKeyValueDhInitialize(&dhKeyValue);
2506
0
    if(ret < 0) {
2507
0
        xmlSecInternalError("xmlSecOpenSSLKeyValueDhInitialize",
2508
0
            xmlSecKeyDataGetName(data));
2509
0
        goto done;
2510
0
    }
2511
2512
0
    ret = xmlSecOpenSSLKeyDataDhGetValue(data, &dhKeyValue);
2513
0
    if((ret < 0) || (dhKeyValue.pub == NULL)) {
2514
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataDhGetValue",
2515
0
            xmlSecKeyDataGetName(data));
2516
0
        goto done;
2517
0
    }
2518
2519
    /* p: optional */
2520
0
    if(dhKeyValue.p != NULL) {
2521
0
        ret = xmlSecOpenSSLSetBNValue(dhKeyValue.p, &(dhValue->p));
2522
0
        if(ret < 0) {
2523
0
            xmlSecInternalError("xmlSecOpenSSLSetBNValue(p)",
2524
0
                xmlSecKeyDataKlassGetName(id));
2525
0
            goto done;
2526
0
        }
2527
0
    }
2528
2529
    /* q: optional */
2530
0
    if(dhKeyValue.q != NULL) {
2531
0
        ret = xmlSecOpenSSLSetBNValue(dhKeyValue.q, &(dhValue->q));
2532
0
        if(ret < 0) {
2533
0
            xmlSecInternalError("xmlSecOpenSSLSetBNValue(q)",
2534
0
                xmlSecKeyDataKlassGetName(id));
2535
0
            goto done;
2536
0
        }
2537
0
    }
2538
2539
    /* generator: optional */
2540
0
    if(dhKeyValue.generator != NULL) {
2541
0
        ret = xmlSecOpenSSLSetBNValue(dhKeyValue.generator, &(dhValue->generator));
2542
0
        if(ret < 0) {
2543
0
            xmlSecInternalError("xmlSecOpenSSLSetBNValue(generator)",
2544
0
                xmlSecKeyDataKlassGetName(id));
2545
0
            goto done;
2546
0
        }
2547
0
    }
2548
2549
    /* public: required */
2550
0
    ret = xmlSecOpenSSLSetBNValue(dhKeyValue.pub, &(dhValue->pub));
2551
0
    if(ret < 0) {
2552
0
        xmlSecInternalError("xmlSecOpenSSLSetBNValue(public)",
2553
0
            xmlSecKeyDataKlassGetName(id));
2554
0
        goto done;
2555
0
    }
2556
2557
    /* seed: optional */
2558
0
    if(dhKeyValue.seed != NULL) {
2559
0
        ret = xmlSecOpenSSLSetBNValue(dhKeyValue.seed, &(dhValue->seed));
2560
0
        if(ret < 0) {
2561
0
            xmlSecInternalError("xmlSecOpenSSLSetBNValue(seed)",
2562
0
                xmlSecKeyDataKlassGetName(id));
2563
0
            goto done;
2564
0
        }
2565
0
    }
2566
2567
    /* pgenCounter: optional */
2568
0
    if(dhKeyValue.pgenCounter != NULL) {
2569
0
        ret = xmlSecOpenSSLSetBNValue(dhKeyValue.pgenCounter, &(dhValue->pgenCounter));
2570
0
        if(ret < 0) {
2571
0
            xmlSecInternalError("xmlSecOpenSSLSetBNValue(pgenCounter)",
2572
0
                xmlSecKeyDataKlassGetName(id));
2573
0
            goto done;
2574
0
        }
2575
0
    }
2576
2577
    /* success */
2578
0
    res = 0;
2579
2580
0
done:
2581
0
    xmlSecOpenSSLKeyValueDhFinalize(&dhKeyValue);
2582
0
    return(res);
2583
0
}
2584
2585
#endif /* XMLSEC_NO_DH */
2586
2587
2588
#ifndef XMLSEC_NO_EC
2589
/******************************************************************************
2590
 *
2591
 * EC XML key representation processing.
2592
 *
2593
 * http://csrc.nist.gov/publications/PubsNISTIRs.html#NIST-IR-7802
2594
 *
2595
 * RFC 4050 [RFC4050] describes a possible &lt;dsig:KeyValue/&gt; representation
2596
 * for an EC key. The representation and processing instructions
2597
 * described in [RFC4050] are not completely compatible with [XMLDSIG-11];
2598
 * therefore, EC keys SHOULD NOT be provided through a &lt;dsig:KeyValue/&gt;
2599
 * element.
2600
 *
2601
 *****************************************************************************/
2602
2603
0
#define XMLSEC_OPENSSL_EC_EVP_NAME                  "EC"
2604
2605
2606
2607
static int              xmlSecOpenSSLKeyDataEcXmlRead           (xmlSecKeyDataId id,
2608
                                                                 xmlSecKeyPtr key,
2609
                                                                 xmlNodePtr node,
2610
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
2611
static int              xmlSecOpenSSLKeyDataEcXmlWrite          (xmlSecKeyDataId id,
2612
                                                                 xmlSecKeyPtr key,
2613
                                                                 xmlNodePtr node,
2614
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
2615
2616
2617
static xmlSecKeyDataPtr xmlSecOpenSSLKeyDataEcRead               (xmlSecKeyDataId id,
2618
                                                                  xmlSecKeyValueEcPtr ecValue);
2619
static int              xmlSecOpenSSLKeyDataEcWrite              (xmlSecKeyDataId id,
2620
                                                                 xmlSecKeyDataPtr data,
2621
                                                                 xmlSecKeyValueEcPtr ecValue);
2622
2623
2624
#if defined(XMLSEC_OPENSSL_API_111)
2625
static const EC_KEY*    xmlSecOpenSSLKeyDataEcGetEcKey          (xmlSecKeyDataPtr data);
2626
#endif /* defined(XMLSEC_OPENSSL_API_111) */
2627
2628
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX(Ec, EC,
2629
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
2630
    xmlSecNodeECKeyValue, xmlSecDSig11Ns,
2631
    NULL,
2632
    xmlSecOpenSSLKeyDataEcXmlRead,
2633
    xmlSecOpenSSLKeyDataEcXmlWrite)
2634
2635
/**
2636
 * @brief The EC key data klass.
2637
 * @return pointer to EC key data klass.
2638
 */
2639
xmlSecKeyDataId
2640
14
xmlSecOpenSSLKeyDataEcGetKlass(void) {
2641
14
    return(&xmlSecOpenSSLKeyDataEcKlass);
2642
14
}
2643
2644
/**
2645
 * @brief Sets the EC key data value to OpenSSL EVP key.
2646
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
2647
 * @param data the pointer to EC key data.
2648
 * @param pKey the pointer to OpenSSL EVP key.
2649
 * @return 0 on success or a negative value otherwise.
2650
 */
2651
int
2652
0
xmlSecOpenSSLKeyDataEcAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
2653
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), -1);
2654
0
    xmlSecAssert2(pKey != NULL, -1);
2655
0
    xmlSecAssert2(EVP_PKEY_base_id(pKey) == EVP_PKEY_EC, -1);
2656
0
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
2657
0
}
2658
2659
/**
2660
 * @brief Gets the OpenSSL EVP key from EC key data.
2661
 * @param data the pointer to EC key data.
2662
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
2663
 */
2664
EVP_PKEY*
2665
0
xmlSecOpenSSLKeyDataEcGetEvp(xmlSecKeyDataPtr data) {
2666
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), NULL);
2667
0
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
2668
0
}
2669
2670
2671
2672
typedef struct _xmlSecOpenSSLKeyDataEcCurveNameAndOID {
2673
    int nid;
2674
    xmlChar name[128];
2675
    xmlChar oid[128];
2676
} xmlSecOpenSSLKeyDataEcCurveNameAndOID;
2677
2678
static const xmlSecOpenSSLKeyDataEcCurveNameAndOID g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[] = {
2679
    { NID_X9_62_prime192v1, SN_X9_62_prime192v1, "1.2.840.10045.3.1.1" }, /* "prime192v1" */
2680
    { NID_X9_62_prime192v2, SN_X9_62_prime192v2, "1.2.840.10045.3.1.2" },
2681
    { NID_X9_62_prime192v3, SN_X9_62_prime192v3, "1.2.840.10045.3.1.3" },
2682
    { NID_X9_62_prime239v1, SN_X9_62_prime239v1, "1.2.840.10045.3.1.4" },
2683
    { NID_X9_62_prime239v2, SN_X9_62_prime239v2, "1.2.840.10045.3.1.5" },
2684
    { NID_X9_62_prime239v3, SN_X9_62_prime239v3, "1.2.840.10045.3.1.6" },
2685
    { NID_X9_62_prime256v1, SN_X9_62_prime256v1, "1.2.840.10045.3.1.7" }, /* prime256v1 */
2686
    { NID_secp224r1, SN_secp224r1, "1.3.132.0.33" }, /* secp224r1 */
2687
    { NID_secp384r1, SN_secp384r1, "1.3.132.0.34" }, /* secp384r1 */
2688
    { NID_secp521r1, SN_secp521r1, "1.3.132.0.35" }  /* secp521r1 */
2689
};
2690
2691
2692
2693
#if !defined(XMLSEC_OPENSSL_API_111)
2694
2695
static const xmlChar*
2696
0
xmlSecOpenSSLKeyDataEcGetOidFromName(const xmlChar* name) {
2697
0
    xmlSecSize size = sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID) / sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[0]);
2698
2699
0
    xmlSecAssert2(name != NULL, NULL);
2700
2701
0
    for(xmlSecSize ii = 0; ii < size; ++ii) {
2702
0
        if(xmlStrcmp(name, g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].name) == 0) {
2703
0
            return(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].oid);
2704
0
        }
2705
0
    }
2706
0
    return(NULL);
2707
0
}
2708
2709
static const xmlChar*
2710
0
xmlSecOpenSSLKeyDataEcGetNameFromOid(const xmlChar* oid) {
2711
0
    xmlSecSize size = sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID) / sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[0]);
2712
2713
0
    xmlSecAssert2(oid != NULL, NULL);
2714
2715
0
    for(xmlSecSize ii = 0; ii < size; ++ii) {
2716
0
        if(xmlStrcmp(oid, g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].oid) == 0) {
2717
0
            return(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].name);
2718
0
        }
2719
0
    }
2720
0
    return(NULL);
2721
0
}
2722
2723
static int
2724
xmlSecOpenSSLKeyDataEcWrite(xmlSecKeyDataId id, xmlSecKeyDataPtr data, xmlSecKeyValueEcPtr ecValue)
2725
0
{
2726
2727
0
    EVP_PKEY* pKey = NULL;
2728
0
    const xmlChar* curve_oid;
2729
0
    char curve_name[128];
2730
0
    size_t curve_name_len = 0;
2731
0
    unsigned char *pubkey_data = NULL;
2732
0
    xmlSecSize pubkey_size;
2733
0
    int ret;
2734
2735
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataEcId, -1);
2736
0
    xmlSecAssert2(data != NULL, -1);
2737
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), -1);
2738
0
    xmlSecAssert2(ecValue != NULL, -1);
2739
0
    xmlSecAssert2(ecValue->curve == NULL, -1);
2740
2741
0
    pKey = xmlSecOpenSSLKeyDataEcGetEvp(data);
2742
0
    xmlSecAssert2(pKey != NULL, -1);
2743
2744
    /* curve name first */
2745
0
    ret = EVP_PKEY_get_utf8_string_param(pKey, OSSL_PKEY_PARAM_GROUP_NAME,
2746
0
            curve_name, sizeof(curve_name), &curve_name_len);
2747
0
    if((ret != 1) || (curve_name_len == 0) || (curve_name_len >= sizeof(curve_name))) {
2748
0
        xmlSecOpenSSLError("EVP_PKEY_get_utf8_string_param(GROUP_NAME)", xmlSecKeyDataGetName(data));
2749
0
        return(-1);
2750
0
    }
2751
    /* just in case */
2752
0
    curve_name[curve_name_len] = '\0';
2753
0
    curve_oid = xmlSecOpenSSLKeyDataEcGetOidFromName(BAD_CAST curve_name);
2754
0
    if(curve_oid == NULL) {
2755
0
        xmlSecInternalError2("xmlSecOpenSSLKeyDataEcGetOidFromName",  xmlSecKeyDataGetName(data),
2756
0
            "curve_name=%s", xmlSecErrorsSafeString(curve_name));
2757
0
        return(-1);
2758
0
    }
2759
0
    ecValue->curve = xmlStrdup(curve_oid);
2760
0
    if(ecValue->curve == NULL) {
2761
0
        xmlSecStrdupError(curve_oid, xmlSecKeyDataGetName(data));
2762
0
        return(-1);
2763
0
    }
2764
2765
    /* pubkey */
2766
0
    pubkey_size = EVP_PKEY_get1_encoded_public_key(pKey, &pubkey_data);
2767
0
    if(pubkey_size == 0) {
2768
0
        xmlSecOpenSSLError("EVP_PKEY_get1_encoded_public_key", xmlSecKeyDataGetName(data));
2769
0
        return(-1);
2770
0
    }
2771
0
    xmlSecAssert2(pubkey_data != NULL, -1);
2772
2773
0
    ret = xmlSecBufferSetData(&(ecValue->pubkey), pubkey_data, pubkey_size);
2774
0
    if(ret < 0) {
2775
0
        xmlSecInternalError("xmlSecBufferSetData(pubkey)", xmlSecKeyDataGetName(data));
2776
0
        OPENSSL_free(pubkey_data);
2777
0
        return (-1);
2778
0
    }
2779
2780
    /* done */
2781
0
    OPENSSL_free(pubkey_data);
2782
0
    return(0);
2783
0
}
2784
2785
static int
2786
0
xmlSecOpenSSLKeyDataEcSetValue(xmlSecKeyDataPtr data, const xmlChar* curveOid, xmlSecBufferPtr pubkey) {
2787
0
    EVP_PKEY* pKey = NULL;
2788
0
    EVP_PKEY_CTX* ctx = NULL;
2789
0
    const xmlChar* curve_name;
2790
0
    xmlSecByte * pubkeyData;
2791
0
    xmlSecSize pubkeyDataSize;
2792
0
    int ret;
2793
0
    int res = -1;
2794
2795
0
    xmlSecAssert2(data != NULL, -1);
2796
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), -1);
2797
0
    xmlSecAssert2(curveOid != NULL, -1);
2798
0
    xmlSecAssert2(pubkey != NULL, -1);
2799
2800
0
    pubkeyData = xmlSecBufferGetData(pubkey);
2801
0
    pubkeyDataSize = xmlSecBufferGetSize(pubkey);
2802
0
    xmlSecAssert2(pubkeyData != NULL, -1);
2803
0
    xmlSecAssert2(pubkeyDataSize > 0, -1);
2804
2805
    /* curve name */
2806
0
    curve_name = xmlSecOpenSSLKeyDataEcGetNameFromOid(curveOid);
2807
0
    if(curve_name == NULL) {
2808
0
        xmlSecInternalError2("xmlSecOpenSSLKeyDataEcGetNameFromOid", xmlSecKeyDataGetName(data),
2809
0
            "curve_oid=%s", xmlSecErrorsSafeString(curveOid));
2810
0
        goto done;
2811
0
    }
2812
2813
    /* create pkey ctx */
2814
0
    ctx = EVP_PKEY_CTX_new_from_name(xmlSecOpenSSLGetLibCtx(), XMLSEC_OPENSSL_EC_EVP_NAME, NULL);
2815
0
    if(ctx == NULL) {
2816
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_name", xmlSecKeyDataGetName(data));
2817
0
        goto done;
2818
0
    }
2819
0
    ret = EVP_PKEY_paramgen_init(ctx);
2820
0
    if(ret != 1) {
2821
0
        xmlSecOpenSSLError("EVP_PKEY_paramgen_init", xmlSecKeyDataGetName(data));
2822
0
        goto done;
2823
0
    }
2824
0
    ret = EVP_PKEY_CTX_set_group_name(ctx, (const char*)curve_name);
2825
0
    if(ret != 1) {
2826
0
        xmlSecOpenSSLError2("EVP_PKEY_CTX_set_group_name", xmlSecKeyDataGetName(data),
2827
0
            "curve=%s", xmlSecErrorsSafeString(curve_name));
2828
0
        goto done;
2829
0
    }
2830
2831
    /* create pkey */
2832
0
    ret = EVP_PKEY_paramgen(ctx, &pKey);
2833
0
    if(ret != 1) {
2834
0
        xmlSecOpenSSLError("EVP_PKEY_paramgen", xmlSecKeyDataGetName(data));
2835
0
        goto done;
2836
0
    }
2837
0
    ret = EVP_PKEY_set1_encoded_public_key(pKey, pubkeyData, pubkeyDataSize);
2838
0
    if(ret != 1) {
2839
0
        xmlSecOpenSSLError("EVP_PKEY_set1_encoded_public_key", xmlSecKeyDataGetName(data));
2840
0
        goto done;
2841
0
    }
2842
2843
    /* set pkey into data */
2844
0
    ret = xmlSecOpenSSLKeyDataEcAdoptEvp(data, pKey);
2845
0
    if(ret < 0) {
2846
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataEcAdoptEvp", xmlSecKeyDataGetName(data));
2847
0
        goto done;
2848
0
    }
2849
0
    pKey = NULL;
2850
2851
    /* success */
2852
0
    res = 0;
2853
2854
0
done:
2855
0
    if(pKey != NULL) {
2856
0
        EVP_PKEY_free(pKey);
2857
0
    }
2858
0
    if(ctx != NULL) {
2859
0
        EVP_PKEY_CTX_free(ctx);
2860
0
    }
2861
0
    return(res);
2862
0
}
2863
2864
#else /* !defined(XMLSEC_OPENSSL_API_111) */
2865
2866
static const xmlChar*
2867
xmlSecOpenSSLKeyDataEcGetOidFromNid(int nid) {
2868
    xmlSecSize size = sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID) / sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[0]);
2869
2870
    xmlSecAssert2(nid != NID_undef, NULL);
2871
2872
    for(xmlSecSize ii = 0; ii < size; ++ii) {
2873
        if(nid == g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].nid) {
2874
            return(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].oid);
2875
        }
2876
    }
2877
    return(NULL);
2878
}
2879
2880
static int
2881
xmlSecOpenSSLKeyDataEcGetNidFromOid(const xmlChar * oid) {
2882
    xmlSecSize size = sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID) / sizeof(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[0]);
2883
2884
    xmlSecAssert2(oid != NULL, NID_undef);
2885
2886
    for(xmlSecSize ii = 0; ii < size; ++ii) {
2887
        if(xmlStrcmp(oid, g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].oid) == 0) {
2888
            return(g_xmlSecOpenSSLKeyDataEcCurveNameAndOID[ii].nid);
2889
        }
2890
    }
2891
    return(NID_undef);
2892
}
2893
2894
static const EC_KEY*
2895
xmlSecOpenSSLKeyDataEcGetEcKey(xmlSecKeyDataPtr data) {
2896
    EVP_PKEY* pKey;
2897
2898
    xmlSecAssert2(data != NULL, NULL);
2899
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), NULL);
2900
2901
    pKey = xmlSecOpenSSLKeyDataEcGetEvp(data);
2902
    xmlSecAssert2((pKey == NULL) || (EVP_PKEY_base_id(pKey) == EVP_PKEY_EC), NULL);
2903
2904
    return((pKey != NULL) ? EVP_PKEY_get0_EC_KEY(pKey) : NULL);
2905
}
2906
2907
/* on success, @p ecKey is copied into @p data and freed by this
2908
 * function, so the caller no longer owns it; on error, the caller
2909
 * is still responsible for destroying it
2910
 */
2911
static int
2912
xmlSecOpenSSLKeyDataEcSetEcKey(xmlSecKeyDataPtr data,  EC_KEY* ecKey) {
2913
    EVP_PKEY* pKey;
2914
    int ret;
2915
2916
    xmlSecAssert2(data != NULL, -1);
2917
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), -1);
2918
    xmlSecAssert2(ecKey != NULL, -1);
2919
2920
    pKey = xmlSecOpenSSLKeyDataEcGetEvp(data);
2921
    xmlSecAssert2(pKey == NULL, -1);
2922
2923
    pKey = EVP_PKEY_new();
2924
    if(pKey == NULL) {
2925
        xmlSecOpenSSLError("EVP_PKEY_new", xmlSecKeyDataGetName(data));
2926
        return(-1);
2927
    }
2928
2929
    ret = EVP_PKEY_set1_EC_KEY(pKey, ecKey);
2930
    if(ret != 1) {
2931
        xmlSecOpenSSLError("EVP_PKEY_set1_EC_KEY", xmlSecKeyDataGetName(data));
2932
        EVP_PKEY_free(pKey);
2933
        return(-1);
2934
    }
2935
2936
    ret = xmlSecOpenSSLKeyDataEcAdoptEvp(data, pKey);
2937
    if(ret < 0) {
2938
        xmlSecInternalError("xmlSecOpenSSLKeyDataEcAdoptEvp", xmlSecKeyDataGetName(data));
2939
        EVP_PKEY_free(pKey);
2940
        return(-1);
2941
    }
2942
    /* data owns pKey now */
2943
2944
    /* success: EVP_PKEY_set1_EC_KEY copied ecKey into pKey, so this function
2945
     * owns ecKey and frees it below */
2946
    EC_KEY_free(ecKey);
2947
    return(0);
2948
}
2949
2950
2951
static int
2952
xmlSecOpenSSLKeyDataEcWrite(xmlSecKeyDataId id, xmlSecKeyDataPtr data, xmlSecKeyValueEcPtr ecValue)
2953
{
2954
    const EC_KEY * ecKey;
2955
    const EC_GROUP * group;
2956
    const EC_POINT * pubkey;
2957
    const xmlChar * curve_oid;
2958
    xmlSecByte * pubkeyData;
2959
    xmlSecSize pubkeySize;
2960
    int nid;
2961
    int ret;
2962
2963
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataEcId, -1);
2964
    xmlSecAssert2(data != NULL, -1);
2965
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), -1);
2966
    xmlSecAssert2(ecValue != NULL, -1);
2967
    xmlSecAssert2(ecValue->curve == NULL, -1);
2968
2969
    ecKey = xmlSecOpenSSLKeyDataEcGetEcKey(data);
2970
    if(ecKey == NULL) {
2971
        xmlSecInternalError("xmlSecOpenSSLKeyDataEcGetEcKey", xmlSecKeyDataGetName(data));
2972
        return(-1);
2973
    }
2974
2975
    group = EC_KEY_get0_group(ecKey);
2976
    if(group == NULL) {
2977
        xmlSecOpenSSLError("EC_KEY_get0_group", xmlSecKeyDataGetName(data));
2978
        return(-1);
2979
    }
2980
2981
    /* curve oid  */
2982
    nid = EC_GROUP_get_curve_name(group);
2983
    if(nid == NID_undef) {
2984
        xmlSecOpenSSLError("EC_GROUP_get_curve_name", xmlSecKeyDataGetName(data));
2985
        return(-1);
2986
    }
2987
    curve_oid = xmlSecOpenSSLKeyDataEcGetOidFromNid(nid);
2988
    if(curve_oid == NULL) {
2989
        xmlSecInternalError2("xmlSecOpenSSLKeyDataEcGetOidFromNid",  xmlSecKeyDataGetName(data),
2990
            "curve_nid=%d", nid);
2991
        return(-1);
2992
    }
2993
    ecValue->curve = xmlStrdup(curve_oid);
2994
    if(ecValue->curve == NULL) {
2995
        xmlSecStrdupError(curve_oid, xmlSecKeyDataGetName(data));
2996
        return(-1);
2997
    }
2998
2999
    /* public key */
3000
    pubkey = EC_KEY_get0_public_key(ecKey);
3001
    if(pubkey == NULL) {
3002
        xmlSecOpenSSLError("EC_KEY_get0_public_key",  xmlSecKeyDataGetName(data));
3003
        return(-1);
3004
    }
3005
3006
    /* the point is encoded as z||x||y, where z is the octet 0x04  */
3007
    pubkeySize = EC_POINT_point2oct(group, pubkey, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
3008
    if(pubkeySize <= 0) {
3009
        xmlSecOpenSSLError("EC_POINT_point2oct(1)",  xmlSecKeyDataGetName(data));
3010
        return(-1);
3011
    }
3012
3013
    ret = xmlSecBufferSetSize(&(ecValue->pubkey), pubkeySize);
3014
    if(ret < 0) {
3015
        xmlSecInternalError2("xmlSecBufferSetSize", NULL,
3016
            "bufSize=" XMLSEC_SIZE_FMT, pubkeySize);
3017
        return (-1);
3018
    }
3019
    pubkeyData = xmlSecBufferGetData(&(ecValue->pubkey));
3020
    xmlSecAssert2(pubkeyData != NULL, -1);
3021
3022
    pubkeySize = EC_POINT_point2oct(group, pubkey, POINT_CONVERSION_UNCOMPRESSED, pubkeyData, pubkeySize, NULL);
3023
    if(pubkeySize <= 0) {
3024
        xmlSecOpenSSLError("EC_POINT_point2oct(2)",  xmlSecKeyDataGetName(data));
3025
        return(-1);
3026
    }
3027
3028
    /* just in case, reset the size again */
3029
    ret = xmlSecBufferSetSize(&(ecValue->pubkey), pubkeySize);
3030
    if(ret < 0) {
3031
        xmlSecInternalError2("xmlSecBufferSetSize", NULL,
3032
            "bufSize=" XMLSEC_SIZE_FMT, pubkeySize);
3033
        return (-1);
3034
    }
3035
3036
    /* done */
3037
    return(0);
3038
}
3039
3040
static int
3041
xmlSecOpenSSLKeyDataEcSetValue(xmlSecKeyDataPtr data, const xmlChar* curveOid, xmlSecBufferPtr pubkey) {
3042
    EC_KEY *eckey = NULL;
3043
    EC_GROUP * group = NULL;
3044
    EC_POINT *point = NULL;
3045
    xmlSecByte * pubkeyData;
3046
    xmlSecSize pubkeySize;
3047
    int nid;
3048
    int ret;
3049
    int res = -1;
3050
3051
    xmlSecAssert2(data != NULL, -1);
3052
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEcId), -1);
3053
    xmlSecAssert2(curveOid != NULL, -1);
3054
    xmlSecAssert2(pubkey != NULL, -1);
3055
3056
    pubkeyData = xmlSecBufferGetData(pubkey);
3057
    pubkeySize = xmlSecBufferGetSize(pubkey);
3058
    xmlSecAssert2(pubkeyData != NULL, -1);
3059
    xmlSecAssert2(pubkeySize > 0, -1);
3060
3061
    /* create group from curve oid */
3062
    nid = xmlSecOpenSSLKeyDataEcGetNidFromOid(curveOid);
3063
    if(nid == NID_undef) {
3064
        xmlSecInternalError2("xmlSecOpenSSLKeyDataEcGetNidFromOid",  xmlSecKeyDataGetName(data),
3065
            "curve_oid=%s", xmlSecErrorsSafeString(curveOid));
3066
        goto done;
3067
    }
3068
3069
    group = EC_GROUP_new_by_curve_name(nid);
3070
    if (group == NULL) {
3071
        xmlSecOpenSSLError2("EC_GROUP_new_by_curve_name",  xmlSecKeyDataGetName(data),
3072
            "nid=%d", nid);
3073
        goto done;
3074
    }
3075
3076
    /* get public key (point) */
3077
    point = EC_POINT_new(group);
3078
    if(point == NULL) {
3079
        xmlSecOpenSSLError("EC_POINT_new",  xmlSecKeyDataGetName(data));
3080
        goto done;
3081
    }
3082
    /* EC_POINT_oct2point() validates that the point is on the curve */
3083
    ret = EC_POINT_oct2point(group, point, pubkeyData, pubkeySize, NULL);
3084
    if(ret != 1) {
3085
        xmlSecOpenSSLError("EC_POINT_oct2point",  xmlSecKeyDataGetName(data));
3086
        goto done;
3087
    }
3088
3089
    /* finally create key */
3090
    eckey = EC_KEY_new();
3091
    if(eckey == NULL) {
3092
        xmlSecOpenSSLError("EC_KEY_new",  xmlSecKeyDataGetName(data));
3093
        goto done;
3094
    }
3095
3096
    ret = EC_KEY_set_group(eckey, group);
3097
    if(ret != 1) {
3098
        xmlSecOpenSSLError("EC_KEY_set_group",  xmlSecKeyDataGetName(data));
3099
        goto done;
3100
    }
3101
3102
    ret = EC_KEY_set_public_key(eckey, point);
3103
    if(ret != 1) {
3104
        xmlSecOpenSSLError("EC_KEY_set_public_key",  xmlSecKeyDataGetName(data));
3105
        goto done;
3106
    }
3107
3108
    /* and set in the data */
3109
    ret = xmlSecOpenSSLKeyDataEcSetEcKey(data, eckey);
3110
    if(ret < 0) {
3111
        xmlSecInternalError("xmlSecOpenSSLKeyDataEcSetEcKey", xmlSecKeyDataGetName(data));
3112
        goto done;
3113
    }
3114
    eckey = NULL; /* data holds a copy of eckey now */
3115
3116
    /* success */
3117
    res = 0;
3118
3119
done:
3120
    if(point != NULL) {
3121
        EC_POINT_free(point);
3122
    }
3123
    if(group != NULL) {
3124
        EC_GROUP_free(group);
3125
    }
3126
    if(eckey != NULL) {
3127
        EC_KEY_free(eckey);
3128
    }
3129
    return(res);
3130
}
3131
3132
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
3133
3134
static int
3135
xmlSecOpenSSLKeyDataEcXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
3136
0
                               xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
3137
3138
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataEcId, -1);
3139
0
    return(xmlSecKeyDataEcXmlRead(id, key, node, keyInfoCtx,
3140
0
        xmlSecOpenSSLKeyDataEcRead));
3141
0
}
3142
3143
static int
3144
xmlSecOpenSSLKeyDataEcXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
3145
0
                                xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
3146
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataEcId, -1);
3147
0
    return(xmlSecKeyDataEcXmlWrite(id, key, node, keyInfoCtx,
3148
0
        xmlSecBase64GetDefaultLineSize(), 1, /* add line breaks */
3149
0
        xmlSecOpenSSLKeyDataEcWrite));
3150
0
}
3151
3152
static xmlSecKeyDataPtr
3153
0
xmlSecOpenSSLKeyDataEcRead(xmlSecKeyDataId id, xmlSecKeyValueEcPtr ecValue) {
3154
0
    xmlSecKeyDataPtr data = NULL;
3155
0
    xmlSecKeyDataPtr res = NULL;
3156
0
    int ret;
3157
3158
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataEcId, NULL);
3159
0
    xmlSecAssert2(ecValue != NULL, NULL);
3160
0
    xmlSecAssert2(ecValue->curve != NULL, NULL);
3161
3162
    /* create key data */
3163
0
    data = xmlSecKeyDataCreate(id);
3164
0
    if(data == NULL) {
3165
0
        xmlSecInternalError("xmlSecKeyDataCreate", xmlSecKeyDataKlassGetName(id));
3166
0
        goto done;
3167
0
    }
3168
3169
0
    ret = xmlSecOpenSSLKeyDataEcSetValue(data, ecValue->curve, &(ecValue->pubkey));
3170
0
    if(ret < 0) {
3171
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataEcSetValue", xmlSecKeyDataKlassGetName(id));
3172
0
        goto done;
3173
0
    }
3174
3175
    /* success */
3176
0
    res = data;
3177
0
    data = NULL;
3178
3179
0
done:
3180
0
    if(data != NULL) {
3181
0
        xmlSecKeyDataDestroy(data);
3182
0
    }
3183
0
    return(res);
3184
0
}
3185
3186
3187
#endif /* XMLSEC_NO_EC */
3188
3189
#ifndef XMLSEC_NO_RSA
3190
3191
/**
3192
 * @brief Returns 0 if @p pKey is a valid RSA key type, 1 if it is not, or a negative value if an error occurs.
3193
 * @param pKey the EVP key to check
3194
 *
3195
 */
3196
int
3197
4
xmlSecOpenSSLKeyValueRsaCheckKeyType(EVP_PKEY* pKey) {
3198
4
    xmlSecAssert2(pKey != NULL, -1);
3199
3200
4
    switch(EVP_PKEY_base_id(pKey)) {
3201
4
    case EVP_PKEY_RSA:
3202
4
    case EVP_PKEY_RSA2:
3203
4
    case EVP_PKEY_RSA_PSS:
3204
4
        return(0);
3205
0
    default:
3206
0
        return(1);
3207
4
    }
3208
4
}
3209
3210
/**
3211
 * @brief Holds the parts of OpenSSL RSA key.
3212
 */
3213
typedef struct _xmlSecOpenSSLKeyValueRsa {
3214
    BIGNUM* n;
3215
    BIGNUM* e;
3216
    BIGNUM* d;
3217
    int notOwner;
3218
} xmlSecOpenSSLKeyValueRsa, *xmlSecOpenSSLKeyValueRsaPtr;
3219
3220
static int
3221
0
xmlSecOpenSSLKeyValueRsaInitialize(xmlSecOpenSSLKeyValueRsaPtr rsaKeyValue) {
3222
0
    xmlSecAssert2(rsaKeyValue != NULL, -1);
3223
0
    memset(rsaKeyValue, 0, sizeof(*rsaKeyValue));
3224
0
    return(0);
3225
0
}
3226
3227
static void
3228
0
xmlSecOpenSSLKeyValueRsaFinalize(xmlSecOpenSSLKeyValueRsaPtr rsaKeyValue) {
3229
0
    xmlSecAssert(rsaKeyValue != NULL);
3230
3231
0
    if((rsaKeyValue->notOwner == 0) && (rsaKeyValue->n != NULL)) {
3232
0
        BN_clear_free(rsaKeyValue->n);
3233
0
    }
3234
0
    if((rsaKeyValue->notOwner == 0) && (rsaKeyValue->e != NULL)) {
3235
0
        BN_clear_free(rsaKeyValue->e);
3236
0
    }
3237
0
    if((rsaKeyValue->notOwner == 0) && (rsaKeyValue->d != NULL)) {
3238
0
        BN_clear_free(rsaKeyValue->d);
3239
0
    }
3240
0
    OPENSSL_cleanse(rsaKeyValue, sizeof(*rsaKeyValue));
3241
0
}
3242
3243
/******************************************************************************
3244
 *
3245
 * The RSAKeyValue Element (http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue)
3246
 *
3247
 *****************************************************************************/
3248
3249
0
#define XMLSEC_OPENSSL_RSA_EVP_NAME                  "RSA"
3250
3251
static int              xmlSecOpenSSLKeyDataRsaXmlRead          (xmlSecKeyDataId id,
3252
                                                                 xmlSecKeyPtr key,
3253
                                                                 xmlNodePtr node,
3254
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
3255
static int              xmlSecOpenSSLKeyDataRsaXmlWrite         (xmlSecKeyDataId id,
3256
                                                                 xmlSecKeyPtr key,
3257
                                                                 xmlNodePtr node,
3258
                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
3259
static int              xmlSecOpenSSLKeyDataRsaGenerate         (xmlSecKeyDataPtr data,
3260
                                                                 xmlSecSize sizeBits,
3261
                                                                 xmlSecKeyDataType type);
3262
3263
static xmlSecKeyDataPtr xmlSecOpenSSLKeyDataRsaRead             (xmlSecKeyDataId id,
3264
                                                                 xmlSecKeyValueRsaPtr rsaValue);
3265
static int              xmlSecOpenSSLKeyDataRsaWrite            (xmlSecKeyDataId id,
3266
                                                                 xmlSecKeyDataPtr data,
3267
                                                                 xmlSecKeyValueRsaPtr rsaValue,
3268
                                                                 int writePrivateKey);
3269
3270
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX(Rsa, RSA,
3271
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
3272
    xmlSecNodeRSAKeyValue, xmlSecDSigNs,
3273
    xmlSecOpenSSLKeyDataRsaGenerate,
3274
    xmlSecOpenSSLKeyDataRsaXmlRead,
3275
    xmlSecOpenSSLKeyDataRsaXmlWrite)
3276
3277
/**
3278
 * @brief The OpenSSL RSA key data klass.
3279
 * @return pointer to OpenSSL RSA key data klass.
3280
 */
3281
xmlSecKeyDataId
3282
4.61k
xmlSecOpenSSLKeyDataRsaGetKlass(void) {
3283
4.61k
    return(&xmlSecOpenSSLKeyDataRsaKlass);
3284
4.61k
}
3285
3286
3287
3288
/**
3289
 * @brief Sets the RSA key data value to OpenSSL EVP key.
3290
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
3291
 * @param data the pointer to RSA key data.
3292
 * @param pKey the pointer to OpenSSL EVP key.
3293
 * @return 0 on success or a negative value otherwise.
3294
 */
3295
int
3296
0
xmlSecOpenSSLKeyDataRsaAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
3297
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3298
0
    xmlSecAssert2(pKey != NULL, -1);
3299
0
    xmlSecAssert2(xmlSecOpenSSLKeyValueRsaCheckKeyType(pKey) == 0, -1);
3300
3301
0
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
3302
0
}
3303
3304
/**
3305
 * @brief Gets the OpenSSL EVP key from RSA key data.
3306
 * @param data the pointer to RSA key data.
3307
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
3308
 */
3309
EVP_PKEY*
3310
4
xmlSecOpenSSLKeyDataRsaGetEvp(xmlSecKeyDataPtr data) {
3311
4
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), NULL);
3312
3313
4
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
3314
4
}
3315
3316
3317
static int
3318
xmlSecOpenSSLKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
3319
0
                               xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
3320
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataRsaId, -1);
3321
0
    return(xmlSecKeyDataRsaXmlRead(id, key, node, keyInfoCtx,
3322
0
        xmlSecOpenSSLKeyDataRsaRead));
3323
3324
0
}
3325
3326
static int
3327
xmlSecOpenSSLKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
3328
0
                            xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
3329
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataRsaId, -1);
3330
0
    return(xmlSecKeyDataRsaXmlWrite(id, key, node, keyInfoCtx,
3331
0
        xmlSecBase64GetDefaultLineSize(), 1, /* add line breaks */
3332
0
        xmlSecOpenSSLKeyDataRsaWrite));
3333
0
}
3334
3335
#if !defined(XMLSEC_OPENSSL_API_111)
3336
3337
static int
3338
0
xmlSecOpenSSLKeyDataRsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type XMLSEC_ATTRIBUTE_UNUSED) {
3339
0
    EVP_PKEY_CTX* pctx = NULL;
3340
0
    OSSL_PARAM_BLD* param_bld = NULL;
3341
0
    OSSL_PARAM* params = NULL;
3342
0
    EVP_PKEY* pKey = NULL;
3343
0
    BIGNUM* publicExponent = NULL;
3344
0
    int res = -1;
3345
0
    int ret;
3346
3347
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3348
0
    xmlSecAssert2(sizeBits > 0, -1);
3349
0
    XMLSEC_UNREFERENCED(type);
3350
3351
    /* create publicExponent */
3352
0
    publicExponent = BN_new();
3353
0
    if(publicExponent == NULL) {
3354
0
        xmlSecOpenSSLError("BN_new",
3355
0
            xmlSecKeyDataGetName(data));
3356
0
        goto done;
3357
0
    }
3358
3359
0
    ret = BN_set_word(publicExponent, RSA_F4);
3360
0
    if(ret != 1) {
3361
0
        xmlSecOpenSSLError("BN_set_word",
3362
0
            xmlSecKeyDataGetName(data));
3363
0
        goto done;
3364
0
    }
3365
3366
0
    pctx = EVP_PKEY_CTX_new_from_name(xmlSecOpenSSLGetLibCtx(), XMLSEC_OPENSSL_RSA_EVP_NAME, NULL);
3367
0
    if(pctx == NULL) {
3368
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_name",
3369
0
            xmlSecKeyDataGetName(data));
3370
0
        goto done;
3371
0
    }
3372
0
    ret = EVP_PKEY_keygen_init(pctx);
3373
0
    if(ret <= 0) {
3374
0
        xmlSecOpenSSLError("EVP_PKEY_keygen_init",
3375
0
            xmlSecKeyDataGetName(data));
3376
0
        goto done;
3377
0
    }
3378
0
    param_bld = OSSL_PARAM_BLD_new();
3379
0
    if(param_bld == NULL) {
3380
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_new",
3381
0
            xmlSecKeyDataGetName(data));
3382
0
        goto done;
3383
0
    }
3384
0
    if(OSSL_PARAM_BLD_push_size_t(param_bld, OSSL_PKEY_PARAM_BITS, sizeBits) != 1) {
3385
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_size_t(bits)",
3386
0
            xmlSecKeyDataGetName(data));
3387
0
        goto done;
3388
0
    }
3389
0
    if(OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, publicExponent) != 1) {
3390
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(publicExponent)",
3391
0
            xmlSecKeyDataGetName(data));
3392
0
        goto done;
3393
0
    }
3394
3395
0
    params = OSSL_PARAM_BLD_to_param(param_bld);
3396
0
    if(params == NULL) {
3397
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_to_param",
3398
0
            xmlSecKeyDataGetName(data));
3399
0
        goto done;
3400
0
    }
3401
0
    ret = EVP_PKEY_CTX_set_params(pctx, params);
3402
0
    if(ret <= 0) {
3403
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_set_params",
3404
0
            xmlSecKeyDataGetName(data));
3405
0
        goto done;
3406
0
    }
3407
0
    ret = EVP_PKEY_generate(pctx, &pKey);
3408
0
    if(ret <= 0) {
3409
0
        xmlSecOpenSSLError2("EVP_PKEY_generate",
3410
0
            xmlSecKeyDataGetName(data),
3411
0
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
3412
0
        goto done;
3413
0
    }
3414
0
    ret = xmlSecOpenSSLKeyDataRsaAdoptEvp(data, pKey);
3415
0
    if(ret < 0) {
3416
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaAdoptEvp",
3417
0
            xmlSecKeyDataGetName(data));
3418
0
        goto done;
3419
0
    }
3420
0
    pKey = NULL;
3421
3422
    /* success */
3423
0
    res = 0;
3424
3425
0
done:
3426
0
    if(pKey != NULL) {
3427
0
        EVP_PKEY_free(pKey);
3428
0
    }
3429
0
    if(params != NULL) {
3430
0
        OSSL_PARAM_free(params);
3431
0
    }
3432
0
    if(param_bld != NULL) {
3433
0
        OSSL_PARAM_BLD_free(param_bld);
3434
0
    }
3435
0
    if(pctx != NULL) {
3436
0
        EVP_PKEY_CTX_free(pctx);
3437
0
    }
3438
0
    if(publicExponent != NULL) {
3439
0
        BN_clear_free(publicExponent);
3440
0
    }
3441
0
    return(res);
3442
0
}
3443
3444
static int
3445
0
xmlSecOpenSSLKeyDataRsaGetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueRsaPtr rsaKeyValue) {
3446
0
    EVP_PKEY* pKey = NULL;
3447
0
    int ret;
3448
3449
0
    xmlSecAssert2(data != NULL, -1);
3450
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3451
0
    xmlSecAssert2(rsaKeyValue != NULL, -1);
3452
3453
0
    pKey = xmlSecOpenSSLKeyDataRsaGetEvp(data);
3454
0
    xmlSecAssert2(pKey != NULL, -1);
3455
3456
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_RSA_N, &(rsaKeyValue->n));
3457
0
    if((ret != 1) || (rsaKeyValue->n == NULL)) {
3458
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(n)", xmlSecKeyDataGetName(data));
3459
0
        return(-1);
3460
0
    }
3461
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_RSA_E, &(rsaKeyValue->e));
3462
0
    if((ret != 1) || (rsaKeyValue->e == NULL)) {
3463
0
        xmlSecOpenSSLError("EVP_PKEY_get_bn_param(e)", xmlSecKeyDataGetName(data));
3464
0
        return(-1);
3465
0
    }
3466
0
    ret = EVP_PKEY_get_bn_param(pKey, OSSL_PKEY_PARAM_RSA_D, &(rsaKeyValue->d));
3467
0
    if((ret != 1) || (rsaKeyValue->d == NULL)) {
3468
        /* ignore the error since public keys don't have private component */
3469
0
    }
3470
3471
    /* success */
3472
0
    return(0);
3473
0
}
3474
3475
static int
3476
0
xmlSecOpenSSLKeyDataRsaSetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueRsaPtr rsaKeyValue) {
3477
0
    EVP_PKEY* pKey = NULL;
3478
0
    EVP_PKEY_CTX* ctx = NULL;
3479
0
    OSSL_PARAM_BLD* param_bld = NULL;
3480
0
    OSSL_PARAM* params = NULL;
3481
0
    int ret;
3482
0
    int res = -1;
3483
3484
0
    xmlSecAssert2(data != NULL, -1);
3485
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3486
0
    xmlSecAssert2(rsaKeyValue != NULL, -1);
3487
0
    xmlSecAssert2(rsaKeyValue->e != NULL, -1);
3488
0
    xmlSecAssert2(rsaKeyValue->n != NULL, -1);
3489
3490
0
    param_bld = OSSL_PARAM_BLD_new();
3491
0
    if(param_bld == NULL) {
3492
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_new",
3493
0
            xmlSecKeyDataGetName(data));
3494
0
        goto done;
3495
0
    }
3496
0
    ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, rsaKeyValue->n);
3497
0
    if(ret != 1) {
3498
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(n)",
3499
0
            xmlSecKeyDataGetName(data));
3500
0
        goto done;
3501
0
    }
3502
0
    ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, rsaKeyValue->e);
3503
0
    if(ret != 1) {
3504
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(e)",
3505
0
            xmlSecKeyDataGetName(data));
3506
0
        goto done;
3507
0
    }
3508
0
    if(rsaKeyValue->d != NULL) {
3509
0
        ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, rsaKeyValue->d);
3510
0
        if(ret != 1) {
3511
0
            xmlSecOpenSSLError("OSSL_PARAM_BLD_push_BN(d)",
3512
0
                xmlSecKeyDataGetName(data));
3513
0
            goto done;
3514
0
        }
3515
0
    }
3516
3517
0
    params = OSSL_PARAM_BLD_to_param(param_bld);
3518
0
    if(params == NULL) {
3519
0
        xmlSecOpenSSLError("OSSL_PARAM_BLD_to_param",
3520
0
            xmlSecKeyDataGetName(data));
3521
0
        goto done;
3522
0
    }
3523
0
    ctx = EVP_PKEY_CTX_new_from_name(xmlSecOpenSSLGetLibCtx(), XMLSEC_OPENSSL_RSA_EVP_NAME, NULL);
3524
0
    if(ctx == NULL) {
3525
0
        xmlSecOpenSSLError("EVP_PKEY_CTX_new_from_name",
3526
0
            xmlSecKeyDataGetName(data));
3527
0
        goto done;
3528
0
    }
3529
3530
0
    ret = EVP_PKEY_fromdata_init(ctx);
3531
0
    if(ret <= 0) {
3532
0
        xmlSecOpenSSLError("EVP_PKEY_fromdata_init",
3533
0
            xmlSecKeyDataGetName(data));
3534
0
        goto done;
3535
0
    }
3536
    /*
3537
     * If the private key is not present, import only the public key.
3538
     * Importing a keypair with an empty private key parameter fails.
3539
     */
3540
0
    ret = EVP_PKEY_fromdata(ctx, &pKey, (rsaKeyValue->d != NULL) ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY, params);
3541
0
    if(ret <= 0) {
3542
0
        xmlSecOpenSSLError("EVP_PKEY_fromdata",
3543
0
            xmlSecKeyDataGetName(data));
3544
0
        goto done;
3545
0
    }
3546
0
    ret = xmlSecOpenSSLKeyDataRsaAdoptEvp(data, pKey);
3547
0
    if(ret < 0) {
3548
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaAdoptEvp",
3549
0
            xmlSecKeyDataGetName(data));
3550
0
        goto done;
3551
0
    }
3552
0
    pKey = NULL;
3553
3554
    /* success */
3555
0
    res = 0;
3556
3557
0
done:
3558
0
    if(pKey != NULL) {
3559
0
        EVP_PKEY_free(pKey);
3560
0
    }
3561
0
    if(ctx != NULL) {
3562
0
        EVP_PKEY_CTX_free(ctx);
3563
0
    }
3564
0
    if(params != NULL) {
3565
0
        OSSL_PARAM_free(params);
3566
0
    }
3567
0
    if(param_bld != NULL) {
3568
0
        OSSL_PARAM_BLD_free(param_bld);
3569
0
    }
3570
0
    return(res);
3571
0
}
3572
#else /* !defined(XMLSEC_OPENSSL_API_111) */
3573
3574
/* on success, the ownership of @p rsa is transferred to @p data,
3575
 * on error, the caller is still responsible for destroying it
3576
 */
3577
static int
3578
xmlSecOpenSSLKeyDataRsaAdoptRsa(xmlSecKeyDataPtr data, RSA* rsa) {
3579
    EVP_PKEY* pKey = NULL;
3580
    int ret;
3581
3582
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3583
    xmlSecAssert2(rsa != NULL, -1);
3584
3585
    /* construct new EVP_PKEY */
3586
    pKey = EVP_PKEY_new();
3587
    if(pKey == NULL) {
3588
        xmlSecOpenSSLError("EVP_PKEY_new", xmlSecKeyDataGetName(data));
3589
        return(-1);
3590
    }
3591
    ret = EVP_PKEY_assign_RSA(pKey, rsa);
3592
    if(ret != 1) {
3593
        xmlSecOpenSSLError("EVP_PKEY_assign_RSA", xmlSecKeyDataGetName(data));
3594
        EVP_PKEY_free(pKey);
3595
        return(-1);
3596
    }
3597
    /* pKey owns rsa now */
3598
3599
    ret = xmlSecOpenSSLKeyDataRsaAdoptEvp(data, pKey);
3600
    if(ret < 0) {
3601
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaAdoptEvp", xmlSecKeyDataGetName(data));
3602
        RSA_up_ref(rsa); /* give rsa back to the caller (ignore return value) */
3603
        EVP_PKEY_free(pKey);
3604
        return(-1);
3605
    }
3606
    /* data owns pKey now */
3607
3608
    /* success: data -> pKey owns rsa now */
3609
    return(0);
3610
}
3611
3612
static RSA*
3613
xmlSecOpenSSLKeyDataRsaGetRsa(xmlSecKeyDataPtr data) {
3614
    EVP_PKEY* pKey;
3615
3616
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), NULL);
3617
3618
    pKey = xmlSecOpenSSLKeyDataRsaGetEvp(data);
3619
    if (pKey == NULL) {
3620
        return(NULL);
3621
    }
3622
    xmlSecAssert2(xmlSecOpenSSLKeyValueRsaCheckKeyType(pKey) == 0, NULL);
3623
    return(EVP_PKEY_get0_RSA(pKey));
3624
}
3625
3626
static int
3627
xmlSecOpenSSLKeyDataRsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type XMLSEC_ATTRIBUTE_UNUSED) {
3628
    RSA* rsa = NULL;
3629
    int lenBits;
3630
    BIGNUM* publicExponent = NULL;
3631
    int res = -1;
3632
    int ret;
3633
3634
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3635
    xmlSecAssert2(sizeBits > 0, -1);
3636
    XMLSEC_UNREFERENCED(type);
3637
3638
    /* create publicExponent */
3639
    publicExponent = BN_new();
3640
    if(publicExponent == NULL) {
3641
        xmlSecOpenSSLError("BN_new", xmlSecKeyDataGetName(data));
3642
        goto done;
3643
    }
3644
3645
    ret = BN_set_word(publicExponent, RSA_F4);
3646
    if(ret != 1) {
3647
        xmlSecOpenSSLError("BN_set_word", xmlSecKeyDataGetName(data));
3648
        goto done;
3649
    }
3650
3651
    rsa = RSA_new();
3652
    if(rsa == NULL) {
3653
        xmlSecOpenSSLError("RSA_new", xmlSecKeyDataGetName(data));
3654
        goto done;
3655
    }
3656
3657
    XMLSEC_SAFE_CAST_SIZE_TO_INT(sizeBits, lenBits, goto done, NULL);
3658
    ret = RSA_generate_key_ex(rsa, lenBits, publicExponent, NULL);
3659
    if(ret != 1) {
3660
        xmlSecOpenSSLError2("RSA_generate_key_ex", xmlSecKeyDataGetName(data),
3661
            "sizeBits=" XMLSEC_SIZE_FMT, sizeBits);
3662
        goto done;
3663
    }
3664
3665
    ret = xmlSecOpenSSLKeyDataRsaAdoptRsa(data, rsa);
3666
    if(ret < 0) {
3667
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaAdoptRsa", xmlSecKeyDataGetName(data));
3668
        goto done;
3669
    }
3670
    rsa = NULL;  /* ownership transferred to AdoptRsa */
3671
3672
    /* success */
3673
    res = 0;
3674
3675
done:
3676
    if(rsa != NULL) {
3677
        RSA_free(rsa);
3678
    }
3679
    if(publicExponent != NULL) {
3680
        BN_clear_free(publicExponent);
3681
    }
3682
    return(res);
3683
}
3684
3685
static int
3686
xmlSecOpenSSLKeyDataRsaGetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueRsaPtr rsaKeyValue) {
3687
    RSA* rsa = NULL;
3688
3689
    xmlSecAssert2(data != NULL, -1);
3690
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3691
    xmlSecAssert2(rsaKeyValue != NULL, -1);
3692
3693
    /* ensure the values are not getting free'd */
3694
    rsaKeyValue->notOwner = 1;
3695
3696
    rsa = xmlSecOpenSSLKeyDataRsaGetRsa(data);
3697
    if(rsa == NULL) {
3698
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaGetRsa", xmlSecKeyDataGetName(data));
3699
        return(-1);
3700
    }
3701
3702
    RSA_get0_key(rsa,
3703
        (const BIGNUM**)(&rsaKeyValue->n),
3704
        (const BIGNUM**)(&rsaKeyValue->e),
3705
        (const BIGNUM**)(&rsaKeyValue->d));
3706
    if((rsaKeyValue->n == NULL) || (rsaKeyValue->e == NULL)) {
3707
        xmlSecOpenSSLError("RSA_get0_key", xmlSecKeyDataGetName(data));
3708
        return(-1);
3709
    }
3710
3711
    /* success */
3712
    return(0);
3713
}
3714
3715
static int
3716
xmlSecOpenSSLKeyDataRsaSetValue(xmlSecKeyDataPtr data, xmlSecOpenSSLKeyValueRsaPtr rsaKeyValue) {
3717
    RSA* rsa = NULL;
3718
    int ret;
3719
    int res = -1;
3720
3721
    xmlSecAssert2(data != NULL, -1);
3722
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3723
    xmlSecAssert2(rsaKeyValue != NULL, -1);
3724
    xmlSecAssert2(rsaKeyValue->e != NULL, -1);
3725
    xmlSecAssert2(rsaKeyValue->n != NULL, -1);
3726
3727
    rsa = RSA_new();
3728
    if(rsa == NULL) {
3729
        xmlSecOpenSSLError("RSA_new", xmlSecKeyDataGetName(data));
3730
        goto done;
3731
    }
3732
    ret = RSA_set0_key(rsa, rsaKeyValue->n, rsaKeyValue->e, rsaKeyValue->d);
3733
    if(ret == 0) {
3734
        xmlSecOpenSSLError("RSA_set0_key",
3735
            xmlSecKeyDataGetName(data));
3736
        goto done;
3737
    }
3738
    /* owned by rsa now */
3739
    rsaKeyValue->n = NULL;
3740
    rsaKeyValue->e = NULL;
3741
    rsaKeyValue->d = NULL;
3742
3743
    ret = xmlSecOpenSSLKeyDataRsaAdoptRsa(data, rsa);
3744
    if(ret < 0) {
3745
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaAdoptRsa",
3746
            xmlSecKeyDataGetName(data));
3747
        goto done;
3748
    }
3749
    rsa = NULL;  /* ownership transferred to AdoptRsa */
3750
3751
    /* success */
3752
    res = 0;
3753
3754
done:
3755
    if(rsa != NULL) {
3756
        RSA_free(rsa);
3757
    }
3758
    return(res);
3759
}
3760
3761
#endif /* !defined(XMLSEC_OPENSSL_API_111) */
3762
3763
3764
static xmlSecKeyDataPtr
3765
0
xmlSecOpenSSLKeyDataRsaRead(xmlSecKeyDataId id, xmlSecKeyValueRsaPtr rsaValue) {
3766
0
    xmlSecKeyDataPtr data = NULL;
3767
0
    xmlSecKeyDataPtr res = NULL;
3768
0
    xmlSecOpenSSLKeyValueRsa rsaKeyValue;
3769
0
    int ret;
3770
3771
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataRsaId, NULL);
3772
0
    xmlSecAssert2(rsaValue != NULL, NULL);
3773
3774
0
    ret = xmlSecOpenSSLKeyValueRsaInitialize(&rsaKeyValue);
3775
0
    if(ret < 0) {
3776
0
        xmlSecInternalError("xmlSecOpenSSLKeyValueRsaInitialize",
3777
0
            xmlSecKeyDataKlassGetName(id));
3778
0
        goto done;
3779
0
    }
3780
3781
    /* Modulus */
3782
0
    ret = xmlSecOpenSSLGetBNValue(&(rsaValue->modulus), &(rsaKeyValue.n));
3783
0
    if(ret < 0) {
3784
0
        xmlSecInternalError("xmlSecOpenSSLGetBNValue(Modulus)",
3785
0
            xmlSecKeyDataKlassGetName(id));
3786
0
        goto done;
3787
0
    }
3788
3789
    /* Exponent */
3790
0
    ret = xmlSecOpenSSLGetBNValue(&(rsaValue->publicExponent), &(rsaKeyValue.e));
3791
0
    if(ret < 0) {
3792
0
        xmlSecInternalError("xmlSecOpenSSLGetBNValue(Exponent)",
3793
0
            xmlSecKeyDataKlassGetName(id));
3794
0
        goto done;
3795
0
    }
3796
    /* PrivateExponent (only for private key) */
3797
0
    if(xmlSecBufferGetSize(&(rsaValue->privateExponent)) > 0) {
3798
        /* d */
3799
0
        ret = xmlSecOpenSSLGetBNValue(&(rsaValue->privateExponent), &(rsaKeyValue.d));
3800
0
        if(ret < 0) {
3801
0
            xmlSecInternalError("xmlSecOpenSSLGetBNValue(d)",
3802
0
                xmlSecKeyDataKlassGetName(id));
3803
0
            goto done;
3804
0
        }
3805
0
    }
3806
3807
0
    data = xmlSecKeyDataCreate(id);
3808
0
    if(data == NULL) {
3809
0
        xmlSecInternalError("xmlSecKeyDataCreate", xmlSecKeyDataKlassGetName(id));
3810
0
        goto done;
3811
0
    }
3812
3813
0
    ret = xmlSecOpenSSLKeyDataRsaSetValue(data, &rsaKeyValue);
3814
0
    if(ret < 0) {
3815
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaSetValue",
3816
0
            xmlSecKeyDataKlassGetName(id));
3817
0
        goto done;
3818
0
    }
3819
3820
    /* success */
3821
0
    res = data;
3822
0
    data = NULL;
3823
3824
0
done:
3825
0
    if(data != NULL) {
3826
0
        xmlSecKeyDataDestroy(data);
3827
0
    }
3828
0
    xmlSecOpenSSLKeyValueRsaFinalize(&rsaKeyValue);
3829
0
    return(res);
3830
0
}
3831
3832
static int
3833
xmlSecOpenSSLKeyDataRsaWrite(xmlSecKeyDataId id, xmlSecKeyDataPtr data,
3834
0
                             xmlSecKeyValueRsaPtr rsaValue, int writePrivateKey) {
3835
3836
0
    xmlSecOpenSSLKeyValueRsa rsaKeyValue;
3837
0
    int ret;
3838
0
    int res = -1;
3839
3840
0
    xmlSecAssert2(id == xmlSecOpenSSLKeyDataRsaId, -1);
3841
0
    xmlSecAssert2(data != NULL, -1);
3842
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataRsaId), -1);
3843
0
    xmlSecAssert2(rsaValue != NULL, -1);
3844
3845
    /* first, get all values */
3846
0
    ret = xmlSecOpenSSLKeyValueRsaInitialize(&rsaKeyValue);
3847
0
    if(ret < 0) {
3848
0
        xmlSecInternalError("xmlSecOpenSSLKeyValueRsaInitialize",
3849
0
            xmlSecKeyDataGetName(data));
3850
0
        goto done;
3851
0
    }
3852
3853
0
    ret = xmlSecOpenSSLKeyDataRsaGetValue(data, &rsaKeyValue);
3854
0
    if(ret < 0) {
3855
0
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaGetValue",
3856
0
            xmlSecKeyDataGetName(data));
3857
0
        goto done;
3858
0
    }
3859
3860
    /* Modulus */
3861
0
    xmlSecAssert2(rsaKeyValue.n != NULL, -1);
3862
0
    ret = xmlSecOpenSSLSetBNValue(rsaKeyValue.n, &(rsaValue->modulus));
3863
0
    if(ret < 0) {
3864
0
        xmlSecInternalError("xmlSecOpenSSLSetBNValue(Modulus)",
3865
0
            xmlSecKeyDataKlassGetName(id));
3866
0
        goto done;
3867
0
    }
3868
3869
    /* Exponent */
3870
0
    xmlSecAssert2(rsaKeyValue.e != NULL, -1);
3871
0
    ret = xmlSecOpenSSLSetBNValue(rsaKeyValue.e, &(rsaValue->publicExponent));
3872
0
    if(ret < 0) {
3873
0
        xmlSecInternalError("xmlSecOpenSSLSetBNValue(Exponent)",
3874
0
            xmlSecKeyDataKlassGetName(id));
3875
0
        goto done;
3876
0
    }
3877
3878
    /* PrivateExponent (only if available and requested) */
3879
0
    if((writePrivateKey != 0) && (rsaKeyValue.d != NULL)) {
3880
0
        ret = xmlSecOpenSSLSetBNValue(rsaKeyValue.d, &(rsaValue->privateExponent));
3881
0
        if(ret < 0) {
3882
0
            xmlSecInternalError("xmlSecOpenSSLSetBNValue(PrivateExponent)",
3883
0
                xmlSecKeyDataKlassGetName(id));
3884
0
            goto done;
3885
0
        }
3886
0
    }
3887
3888
    /* success */
3889
0
    res = 0;
3890
3891
0
done:
3892
0
    xmlSecOpenSSLKeyValueRsaFinalize(&rsaKeyValue);
3893
0
    return(res);
3894
0
}
3895
#endif /* XMLSEC_NO_RSA */
3896
3897
#ifndef XMLSEC_NO_GOST
3898
/******************************************************************************
3899
 *
3900
 * GOST2001 xml key representation processing
3901
 *
3902
 *****************************************************************************/
3903
3904
XMLSEC_OPENSSL_EVP_KEY_KLASS(Gost2001, GOST2001)
3905
3906
/**
3907
 * @brief The GOST2001 key data klass.
3908
 * @return pointer to GOST2001 key data klass.
3909
 */
3910
xmlSecKeyDataId
3911
xmlSecOpenSSLKeyDataGost2001GetKlass(void) {
3912
    return(&xmlSecOpenSSLKeyDataGost2001Klass);
3913
}
3914
3915
#endif /* XMLSEC_NO_GOST */
3916
3917
#ifndef XMLSEC_NO_GOST2012
3918
3919
/******************************************************************************
3920
 *
3921
 * GOST R 34.10-2012 256 bit xml key representation processing
3922
 *
3923
 *****************************************************************************/
3924
3925
XMLSEC_OPENSSL_EVP_KEY_KLASS(GostR3410_2012_256, GostR3410_2012_256)
3926
3927
/**
3928
 * @brief The GOST R 34.10-2012 256 bit key data klass.
3929
 * @return pointer to GOST R 34.10-2012 256 bit key data klass.
3930
 */
3931
xmlSecKeyDataId
3932
xmlSecOpenSSLKeyDataGostR3410_2012_256GetKlass(void) {
3933
    return(&xmlSecOpenSSLKeyDataGostR3410_2012_256Klass);
3934
}
3935
3936
3937
/******************************************************************************
3938
 *
3939
 * GOST R 34.10-2012 512 bit xml key representation processing
3940
 *
3941
 *****************************************************************************/
3942
3943
XMLSEC_OPENSSL_EVP_KEY_KLASS(GostR3410_2012_512, GostR3410_2012_512)
3944
3945
/**
3946
 * @brief The GOST R 34.10-2012 512 bit key data klass.
3947
 * @return pointer to GOST R 34.10-2012 512 bit key data klass.
3948
 */
3949
xmlSecKeyDataId
3950
xmlSecOpenSSLKeyDataGostR3410_2012_512GetKlass(void) {
3951
    return(&xmlSecOpenSSLKeyDataGostR3410_2012_512Klass);
3952
}
3953
3954
#endif /* XMLSEC_NO_GOST2012 */
3955
3956
3957
#ifndef XMLSEC_NO_MLDSA
3958
/*
3959
 * EXPERIMENTAL SUPPORT FOR ML-DSA
3960
 */
3961
static int
3962
xmlSecOpenSSLKeyValueMLDSACheckKeyType(EVP_PKEY* pKey)
3963
{
3964
    xmlSecAssert2(pKey != NULL, -1);
3965
3966
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
3967
    case EVP_PKEY_ML_DSA_44:
3968
    case EVP_PKEY_ML_DSA_65:
3969
    case EVP_PKEY_ML_DSA_87:
3970
        return(0);
3971
    default:
3972
        return(1);
3973
    }
3974
}
3975
3976
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX2(MLDSA, xmlSecNameMLDSAKeyValue, NULL,
3977
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageRetrievalMethodNodeXml,
3978
    NULL, NULL, NULL, NULL, NULL)
3979
3980
/**
3981
 * @brief The OpenSSL ML-DSA data klass.
3982
 * @return pointer to OpenSSL ML-DSA key data klass.
3983
 */
3984
xmlSecKeyDataId
3985
xmlSecOpenSSLKeyDataMLDSAGetKlass(void) {
3986
    return(&xmlSecOpenSSLKeyDataMLDSAKlass);
3987
}
3988
3989
/**
3990
 * @brief Sets the MLDSA key data value to OpenSSL EVP key.
3991
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
3992
 * @param data the pointer to MLDSA key data.
3993
 * @param pKey the pointer to OpenSSL EVP key.
3994
 * @return 0 on success or a negative value otherwise.
3995
 */
3996
int
3997
xmlSecOpenSSLKeyDataMLDSAAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
3998
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataMLDSAId), -1);
3999
    xmlSecAssert2(pKey != NULL, -1);
4000
    xmlSecAssert2(xmlSecOpenSSLKeyValueMLDSACheckKeyType(pKey) == 0, -1);
4001
4002
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
4003
}
4004
4005
/**
4006
 * @brief Gets ML-DSA key (k, l) value: 44 corresponds to (4,4),
4007
 * 65 to (6,5) or 87 to (8,7).
4008
 * @param data the pointer to MLDSA key data.
4009
 *
4010
 * @return 44, 65, or 87 on success or a negative value
4011
 * otherwise.
4012
 */
4013
int
4014
xmlSecOpenSSLKeyDataMLDSAGetKL(xmlSecKeyDataPtr data) {
4015
    EVP_PKEY* pKey;
4016
4017
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataMLDSAId), -1);
4018
4019
    pKey = xmlSecOpenSSLKeyDataMLDSAGetEvp(data);
4020
    xmlSecAssert2(pKey != NULL, -1);
4021
4022
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
4023
    case EVP_PKEY_ML_DSA_44:
4024
        return(44);
4025
    case EVP_PKEY_ML_DSA_65:
4026
        return(65);
4027
    case EVP_PKEY_ML_DSA_87:
4028
        return(87);
4029
    default:
4030
        xmlSecInvalidIntegerTypeError("evp key type", xmlSecOpenSSLEvpKeyGetId(pKey),
4031
                "unsupported evp key type", NULL);
4032
        return(-1);
4033
    }
4034
}
4035
4036
/**
4037
 * @brief Gets the OpenSSL EVP key from MLDSA key data.
4038
 * @param data the pointer to MLDSA key data.
4039
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
4040
 */
4041
EVP_PKEY*
4042
xmlSecOpenSSLKeyDataMLDSAGetEvp(xmlSecKeyDataPtr data) {
4043
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataMLDSAId), NULL);
4044
4045
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
4046
}
4047
4048
4049
#endif /* XMLSEC_NO_MLDSA */
4050
4051
4052
4053
#ifndef XMLSEC_NO_SLHDSA
4054
/*
4055
 * EXPERIMENTAL SUPPORT FOR SLH-DSA
4056
 */
4057
static int
4058
xmlSecOpenSSLKeyValueSLHDSACheckKeyType(EVP_PKEY* pKey)
4059
{
4060
    xmlSecAssert2(pKey != NULL, -1);
4061
4062
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
4063
    case EVP_PKEY_SLH_DSA_SHA2_128F:
4064
    case EVP_PKEY_SLH_DSA_SHA2_128S:
4065
    case EVP_PKEY_SLH_DSA_SHA2_192F:
4066
    case EVP_PKEY_SLH_DSA_SHA2_192S:
4067
    case EVP_PKEY_SLH_DSA_SHA2_256F:
4068
    case EVP_PKEY_SLH_DSA_SHA2_256S:
4069
        return(0);
4070
    default:
4071
        return(1);
4072
    }
4073
}
4074
4075
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX2(SLHDSA, xmlSecNameSLHDSAKeyValue, NULL,
4076
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageRetrievalMethodNodeXml,
4077
    NULL, NULL, NULL, NULL, NULL)
4078
4079
/**
4080
 * @brief The OpenSSL SLH-DSA data klass.
4081
 * @return pointer to OpenSSL SLH-DSA key data klass.
4082
 */
4083
xmlSecKeyDataId
4084
xmlSecOpenSSLKeyDataSLHDSAGetKlass(void) {
4085
    return(&xmlSecOpenSSLKeyDataSLHDSAKlass);
4086
}
4087
4088
/**
4089
 * @brief Sets the SLHDSA key data value to OpenSSL EVP key.
4090
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
4091
 * @param data the pointer to SLHDSA key data.
4092
 * @param pKey the pointer to OpenSSL EVP key.
4093
 * @return 0 on success or a negative value otherwise.
4094
 */
4095
int
4096
xmlSecOpenSSLKeyDataSLHDSAAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
4097
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataSLHDSAId), -1);
4098
    xmlSecAssert2(pKey != NULL, -1);
4099
    xmlSecAssert2(xmlSecOpenSSLKeyValueSLHDSACheckKeyType(pKey) == 0, -1);
4100
4101
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
4102
}
4103
4104
/**
4105
 * @brief Gets the OpenSSL EVP key from SLHDSA key data.
4106
 * @param data the pointer to SLHDSA key data.
4107
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
4108
 */
4109
EVP_PKEY*
4110
xmlSecOpenSSLKeyDataSLHDSAGetEvp(xmlSecKeyDataPtr data) {
4111
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataSLHDSAId), NULL);
4112
4113
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
4114
}
4115
4116
4117
#endif /* XMLSEC_NO_SLHDSA */
4118
4119
4120
4121
#ifndef XMLSEC_NO_MLKEM
4122
static int
4123
xmlSecOpenSSLKeyValueMLKEMCheckKeyType(EVP_PKEY* pKey)
4124
{
4125
    xmlSecAssert2(pKey != NULL, -1);
4126
4127
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
4128
    case NID_ML_KEM_512:
4129
    case NID_ML_KEM_768:
4130
    case NID_ML_KEM_1024:
4131
        return(0);
4132
    default:
4133
        return(1);
4134
    }
4135
}
4136
4137
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX2(MLKEM, xmlSecNameMLKEMKeyValue, NULL,
4138
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageRetrievalMethodNodeXml,
4139
    NULL, NULL, NULL, NULL, NULL)
4140
4141
/**
4142
 * @brief The OpenSSL ML-KEM data klass.
4143
 * @return pointer to OpenSSL ML-KEM key data klass.
4144
 */
4145
xmlSecKeyDataId
4146
xmlSecOpenSSLKeyDataMLKEMGetKlass(void) {
4147
    return(&xmlSecOpenSSLKeyDataMLKEMKlass);
4148
}
4149
4150
/**
4151
 * @brief Sets the ML-KEM key data value to OpenSSL EVP key.
4152
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
4153
 * @param data the pointer to ML-KEM key data.
4154
 * @param pKey the pointer to OpenSSL EVP key.
4155
 * @return 0 on success or a negative value otherwise.
4156
 */
4157
int
4158
xmlSecOpenSSLKeyDataMLKEMAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
4159
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataMLKEMId), -1);
4160
    xmlSecAssert2(pKey != NULL, -1);
4161
    xmlSecAssert2(xmlSecOpenSSLKeyValueMLKEMCheckKeyType(pKey) == 0, -1);
4162
4163
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
4164
}
4165
4166
/**
4167
 * @brief Gets the ML-KEM key size (512, 768, or 1024).
4168
 * @param data the pointer to ML-KEM key data.
4169
 * @return 512, 768, or 1024 on success or a negative value otherwise.
4170
 */
4171
int
4172
xmlSecOpenSSLKeyDataMLKEMGetKL(xmlSecKeyDataPtr data) {
4173
    EVP_PKEY* pKey;
4174
4175
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataMLKEMId), -1);
4176
4177
    pKey = xmlSecOpenSSLKeyDataMLKEMGetEvp(data);
4178
    xmlSecAssert2(pKey != NULL, -1);
4179
4180
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
4181
    case NID_ML_KEM_512:
4182
        return(512);
4183
    case NID_ML_KEM_768:
4184
        return(768);
4185
    case NID_ML_KEM_1024:
4186
        return(1024);
4187
    default:
4188
        xmlSecInvalidIntegerTypeError("evp key type", xmlSecOpenSSLEvpKeyGetId(pKey),
4189
                "unsupported evp key type", NULL);
4190
        return(-1);
4191
    }
4192
}
4193
4194
/**
4195
 * @brief Gets the OpenSSL EVP key from ML-KEM key data.
4196
 * @param data the pointer to ML-KEM key data.
4197
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
4198
 */
4199
EVP_PKEY*
4200
xmlSecOpenSSLKeyDataMLKEMGetEvp(xmlSecKeyDataPtr data) {
4201
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataMLKEMId), NULL);
4202
4203
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
4204
}
4205
4206
4207
#endif /* XMLSEC_NO_MLKEM */
4208
4209
4210
4211
#ifndef XMLSEC_NO_EDDSA
4212
/*
4213
 * EdDSA support
4214
 */
4215
static int
4216
xmlSecOpenSSLKeyValueEdDSACheckKeyType(EVP_PKEY* pKey)
4217
{
4218
    xmlSecAssert2(pKey != NULL, -1);
4219
4220
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
4221
    case EVP_PKEY_ED25519:
4222
    case EVP_PKEY_ED448:
4223
        return(0);
4224
    default:
4225
        return(1);
4226
    }
4227
}
4228
4229
XMLSEC_OPENSSL_EVP_KEY_KLASS_EX2(EdDSA, xmlSecNameEdDSAKeyValue, NULL,
4230
    xmlSecKeyDataUsageReadFromFile | xmlSecKeyDataUsageRetrievalMethodNodeXml,
4231
    NULL, NULL, NULL, NULL, NULL)
4232
4233
/**
4234
 * @brief The OpenSSL EdDSA data klass.
4235
 * @return pointer to OpenSSL EdDSA key data klass.
4236
 */
4237
xmlSecKeyDataId
4238
xmlSecOpenSSLKeyDataEdDSAGetKlass(void) {
4239
    return(&xmlSecOpenSSLKeyDataEdDSAKlass);
4240
}
4241
4242
/**
4243
 * @brief Sets the EdDSA key data value to OpenSSL EVP key.
4244
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
4245
 * @param data the pointer to EdDSA key data.
4246
 * @param pKey the pointer to OpenSSL EVP key.
4247
 * @return 0 on success or a negative value otherwise.
4248
 */
4249
int
4250
xmlSecOpenSSLKeyDataEdDSAAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
4251
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEdDSAId), -1);
4252
    xmlSecAssert2(pKey != NULL, -1);
4253
    xmlSecAssert2(xmlSecOpenSSLKeyValueEdDSACheckKeyType(pKey) == 0, -1);
4254
4255
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
4256
}
4257
4258
/**
4259
 * @brief Gets the OpenSSL EVP key from EdDSA key data.
4260
 * @param data the pointer to EdDSA key data.
4261
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
4262
 */
4263
EVP_PKEY*
4264
xmlSecOpenSSLKeyDataEdDSAGetEvp(xmlSecKeyDataPtr data) {
4265
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataEdDSAId), NULL);
4266
4267
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
4268
}
4269
4270
4271
#endif /* XMLSEC_NO_EDDSA */
4272
4273
4274
#ifndef XMLSEC_NO_XDH
4275
/*
4276
 * XDH support (X25519 and X448 key agreement)
4277
 */
4278
static int
4279
xmlSecOpenSSLKeyValueXdhCheckKeyType(EVP_PKEY* pKey)
4280
0
{
4281
0
    xmlSecAssert2(pKey != NULL, -1);
4282
4283
0
    switch(xmlSecOpenSSLEvpKeyGetId(pKey)) {
4284
0
    case EVP_PKEY_X25519:
4285
0
    case EVP_PKEY_X448:
4286
0
        return(0);
4287
0
    default:
4288
0
        return(1);
4289
0
    }
4290
0
}
4291
4292
XMLSEC_OPENSSL_EVP_KEY_KLASS(Xdh, XDH)
4293
4294
/**
4295
 * @brief The OpenSSL XDH data klass.
4296
 * @return pointer to OpenSSL XDH key data klass.
4297
 */
4298
xmlSecKeyDataId
4299
25
xmlSecOpenSSLKeyDataXdhGetKlass(void) {
4300
25
    return(&xmlSecOpenSSLKeyDataXdhKlass);
4301
25
}
4302
4303
/**
4304
 * @brief Sets the XDH key data value to OpenSSL EVP key.
4305
 * @details On success, ownership of @p pKey transfers to xmlsec; on failure the caller retains ownership.
4306
 * @param data the pointer to XDH key data.
4307
 * @param pKey the pointer to OpenSSL EVP key.
4308
 * @return 0 on success or a negative value otherwise.
4309
 */
4310
int
4311
0
xmlSecOpenSSLKeyDataXdhAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
4312
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataXdhId), -1);
4313
0
    xmlSecAssert2(pKey != NULL, -1);
4314
0
    xmlSecAssert2(xmlSecOpenSSLKeyValueXdhCheckKeyType(pKey) == 0, -1);
4315
4316
0
    return(xmlSecOpenSSLEvpKeyDataAdoptEvp(data, pKey));
4317
0
}
4318
4319
4320
/**
4321
 * @brief Gets the OpenSSL EVP key from XDH key data.
4322
 * @param data the pointer to XDH key data.
4323
 * @return a borrowed pointer to OpenSSL EVP key, or NULL if an error occurs; the caller must NOT free it.
4324
 */
4325
EVP_PKEY*
4326
0
xmlSecOpenSSLKeyDataXdhGetEvp(xmlSecKeyDataPtr data) {
4327
0
    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecOpenSSLKeyDataXdhId), NULL);
4328
4329
0
    return(xmlSecOpenSSLEvpKeyDataGetEvp(data));
4330
0
}
4331
4332
4333
#endif /* XMLSEC_NO_XDH */
4334
4335
/******************************************************************************
4336
 *
4337
 * EVP Util functions
4338
 *
4339
 *****************************************************************************/
4340
#if defined(XMLSEC_OPENSSL_API_350)
4341
4342
/**
4343
 * @brief Creates a provider query string "provider=&lt;name&gt;" for the key in @p pKeyCtx.
4344
 *
4345
 * Determines the owning provider of the key in @p pKeyCtx and writes a property
4346
 * query string of the form "provider=&lt;name&gt;" into @p buf.  This can then be
4347
 * passed to EVP_SIGNATURE_fetch() so that the signature implementation is
4348
 * fetched from the same provider that owns the key (needed e.g. when the key
4349
 * lives in a PKCS#11 token via pkcs11-provider).
4350
 *
4351
 * @param pKeyCtx the pointer to EVP_PKEY_CTX.
4352
 * @param buf the buffer to write the provider query string into.
4353
 * @param bufSize the size of @p buf in bytes.
4354
 * @return pointer to @p buf on success, or NULL if no provider could be
4355
 *         determined or an error occurs.
4356
 */
4357
const xmlChar*
4358
xmlSecOpenSSLEvpGetProviderQuery(EVP_PKEY_CTX* pKeyCtx, xmlChar* buf, int bufSize) {
4359
    EVP_PKEY *pKey;
4360
    const OSSL_PROVIDER *keyProv;
4361
    const char *provName;
4362
    int ret;
4363
4364
    xmlSecAssert2(pKeyCtx != NULL, NULL);
4365
    xmlSecAssert2(buf != NULL, NULL);
4366
    xmlSecAssert2(bufSize > 0, NULL);
4367
4368
    pKey = EVP_PKEY_CTX_get0_pkey(pKeyCtx);
4369
    if(pKey == NULL) {
4370
        return(NULL);
4371
    }
4372
4373
    keyProv = EVP_PKEY_get0_provider(pKey);
4374
    if(keyProv == NULL) {
4375
        return(NULL);
4376
    }
4377
4378
    provName = OSSL_PROVIDER_get0_name(keyProv);
4379
    if(provName == NULL) {
4380
        return(NULL);
4381
    }
4382
4383
    ret = xmlStrPrintf(buf, bufSize, "provider=%s", provName);
4384
    if(ret < 0) {
4385
        xmlSecXmlError("xmlStrPrintf", NULL);
4386
        return(NULL);
4387
    }
4388
    /* xmlStrPrintf returns the length of the formatted string; if it does not
4389
     * fit the buffer the query string would be truncated and is unusable */
4390
    if(ret >= bufSize) {
4391
        xmlSecInvalidSizeOtherError("provider query buffer is too small", NULL);
4392
        return(NULL);
4393
    }
4394
4395
    return(buf);
4396
}
4397
4398
#endif /* defined(XMLSEC_OPENSSL_API_350) */