5 * RSA Algorithms support
7 * This is free software; see Copyright file in the source
8 * distribution for preciese wording.
10 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
19 #include <openssl/rsa.h>
20 #include <openssl/evp.h>
21 #include <openssl/sha.h>
22 #include <openssl/objects.h>
24 #include <libxml/tree.h>
26 #include <xmlsec/xmlsec.h>
27 #include <xmlsec/buffer.h>
28 #include <xmlsec/xmltree.h>
29 #include <xmlsec/keys.h>
30 #include <xmlsec/transforms.h>
31 #include <xmlsec/strings.h>
32 #include <xmlsec/errors.h>
34 #include <xmlsec/openssl/crypto.h>
35 #include <xmlsec/openssl/evp.h>
36 #include <xmlsec/openssl/bn.h>
38 /**************************************************************************
40 * Internal OpenSSL RSA PKCS1 CTX
42 *************************************************************************/
43 typedef struct _xmlSecOpenSSLRsaPkcs1Ctx xmlSecOpenSSLRsaPkcs1Ctx,
44 *xmlSecOpenSSLRsaPkcs1CtxPtr;
45 struct _xmlSecOpenSSLRsaPkcs1Ctx {
49 /*********************************************************************
51 * RSA PKCS1 key transport transform
53 * xmlSecOpenSSLRsaPkcs1Ctx is located after xmlSecTransform
55 ********************************************************************/
56 #define xmlSecOpenSSLRsaPkcs1Size \
57 (sizeof(xmlSecTransform) + sizeof(xmlSecOpenSSLRsaPkcs1Ctx))
58 #define xmlSecOpenSSLRsaPkcs1GetCtx(transform) \
59 ((xmlSecOpenSSLRsaPkcs1CtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
61 static int xmlSecOpenSSLRsaPkcs1Initialize (xmlSecTransformPtr transform);
62 static void xmlSecOpenSSLRsaPkcs1Finalize (xmlSecTransformPtr transform);
63 static int xmlSecOpenSSLRsaPkcs1SetKeyReq (xmlSecTransformPtr transform,
64 xmlSecKeyReqPtr keyReq);
65 static int xmlSecOpenSSLRsaPkcs1SetKey (xmlSecTransformPtr transform,
67 static int xmlSecOpenSSLRsaPkcs1Execute (xmlSecTransformPtr transform,
69 xmlSecTransformCtxPtr transformCtx);
70 static int xmlSecOpenSSLRsaPkcs1Process (xmlSecTransformPtr transform,
71 xmlSecTransformCtxPtr transformCtx);
73 static xmlSecTransformKlass xmlSecOpenSSLRsaPkcs1Klass = {
74 /* klass/object sizes */
75 sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
76 xmlSecOpenSSLRsaPkcs1Size, /* xmlSecSize objSize */
78 xmlSecNameRsaPkcs1, /* const xmlChar* name; */
79 xmlSecHrefRsaPkcs1, /* const xmlChar* href; */
80 xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
82 xmlSecOpenSSLRsaPkcs1Initialize, /* xmlSecTransformInitializeMethod initialize; */
83 xmlSecOpenSSLRsaPkcs1Finalize, /* xmlSecTransformFinalizeMethod finalize; */
84 NULL, /* xmlSecTransformNodeReadMethod readNode; */
85 NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
86 xmlSecOpenSSLRsaPkcs1SetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
87 xmlSecOpenSSLRsaPkcs1SetKey, /* xmlSecTransformSetKeyMethod setKey; */
88 NULL, /* xmlSecTransformValidateMethod validate; */
89 xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
90 xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
91 xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
92 NULL, /* xmlSecTransformPushXmlMethod pushXml; */
93 NULL, /* xmlSecTransformPopXmlMethod popXml; */
94 xmlSecOpenSSLRsaPkcs1Execute, /* xmlSecTransformExecuteMethod execute; */
96 NULL, /* void* reserved0; */
97 NULL, /* void* reserved1; */
101 * xmlSecOpenSSLTransformRsaPkcs1GetKlass:
103 * The RSA-PKCS1 key transport transform klass.
105 * Returns: RSA-PKCS1 key transport transform klass.
108 xmlSecOpenSSLTransformRsaPkcs1GetKlass(void) {
109 return(&xmlSecOpenSSLRsaPkcs1Klass);
113 xmlSecOpenSSLRsaPkcs1Initialize(xmlSecTransformPtr transform) {
114 xmlSecOpenSSLRsaPkcs1CtxPtr ctx;
116 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1);
117 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1);
119 ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform);
120 xmlSecAssert2(ctx != NULL, -1);
122 memset(ctx, 0, sizeof(xmlSecOpenSSLRsaPkcs1Ctx));
127 xmlSecOpenSSLRsaPkcs1Finalize(xmlSecTransformPtr transform) {
128 xmlSecOpenSSLRsaPkcs1CtxPtr ctx;
130 xmlSecAssert(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id));
131 xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size));
133 ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform);
134 xmlSecAssert(ctx != NULL);
136 if(ctx->pKey != NULL) {
137 EVP_PKEY_free(ctx->pKey);
139 memset(ctx, 0, sizeof(xmlSecOpenSSLRsaPkcs1Ctx));
143 xmlSecOpenSSLRsaPkcs1SetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
144 xmlSecOpenSSLRsaPkcs1CtxPtr ctx;
146 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1);
147 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
148 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1);
149 xmlSecAssert2(keyReq != NULL, -1);
151 ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform);
152 xmlSecAssert2(ctx != NULL, -1);
154 keyReq->keyId = xmlSecOpenSSLKeyDataRsaId;
155 if(transform->operation == xmlSecTransformOperationEncrypt) {
156 keyReq->keyType = xmlSecKeyDataTypePublic;
157 keyReq->keyUsage = xmlSecKeyUsageEncrypt;
159 keyReq->keyType = xmlSecKeyDataTypePrivate;
160 keyReq->keyUsage = xmlSecKeyUsageDecrypt;
166 xmlSecOpenSSLRsaPkcs1SetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
167 xmlSecOpenSSLRsaPkcs1CtxPtr ctx;
170 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1);
171 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
172 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1);
173 xmlSecAssert2(key != NULL, -1);
174 xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecOpenSSLKeyDataRsaId), -1);
176 ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform);
177 xmlSecAssert2(ctx != NULL, -1);
178 xmlSecAssert2(ctx->pKey == NULL, -1);
180 pKey = xmlSecOpenSSLKeyDataRsaGetEvp(xmlSecKeyGetValue(key));
182 xmlSecError(XMLSEC_ERRORS_HERE,
183 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
184 "xmlSecOpenSSLKeyDataRsaGetEvp",
185 XMLSEC_ERRORS_R_XMLSEC_FAILED,
186 XMLSEC_ERRORS_NO_MESSAGE);
189 xmlSecAssert2(pKey->type == EVP_PKEY_RSA, -1);
190 xmlSecAssert2(pKey->pkey.rsa != NULL, -1);
192 ctx->pKey = xmlSecOpenSSLEvpKeyDup(pKey);
193 if(ctx->pKey == NULL) {
194 xmlSecError(XMLSEC_ERRORS_HERE,
195 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
196 "xmlSecOpenSSLEvpKeyDup",
197 XMLSEC_ERRORS_R_XMLSEC_FAILED,
198 XMLSEC_ERRORS_NO_MESSAGE);
206 xmlSecOpenSSLRsaPkcs1Execute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
207 xmlSecOpenSSLRsaPkcs1CtxPtr ctx;
210 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1);
211 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
212 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1);
213 xmlSecAssert2(transformCtx != NULL, -1);
215 ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform);
216 xmlSecAssert2(ctx != NULL, -1);
217 xmlSecAssert2(ctx->pKey != NULL, -1);
219 if(transform->status == xmlSecTransformStatusNone) {
220 transform->status = xmlSecTransformStatusWorking;
223 if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) {
224 /* just do nothing */
225 } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) {
226 ret = xmlSecOpenSSLRsaPkcs1Process(transform, transformCtx);
228 xmlSecError(XMLSEC_ERRORS_HERE,
229 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
230 "xmlSecOpenSSLRsaPkcs1Process",
231 XMLSEC_ERRORS_R_XMLSEC_FAILED,
232 XMLSEC_ERRORS_NO_MESSAGE);
235 transform->status = xmlSecTransformStatusFinished;
236 } else if(transform->status == xmlSecTransformStatusFinished) {
237 /* the only way we can get here is if there is no input */
238 xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
240 xmlSecError(XMLSEC_ERRORS_HERE,
241 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
243 XMLSEC_ERRORS_R_INVALID_STATUS,
244 "status=%d", transform->status);
251 xmlSecOpenSSLRsaPkcs1Process(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) {
252 xmlSecOpenSSLRsaPkcs1CtxPtr ctx;
253 xmlSecBufferPtr in, out;
254 xmlSecSize inSize, outSize;
258 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1);
259 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
260 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1);
261 xmlSecAssert2(transformCtx != NULL, -1);
263 ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform);
264 xmlSecAssert2(ctx != NULL, -1);
265 xmlSecAssert2(ctx->pKey != NULL, -1);
266 xmlSecAssert2(ctx->pKey->type == EVP_PKEY_RSA, -1);
267 xmlSecAssert2(ctx->pKey->pkey.rsa != NULL, -1);
269 keySize = RSA_size(ctx->pKey->pkey.rsa);
270 xmlSecAssert2(keySize > 0, -1);
272 in = &(transform->inBuf);
273 out = &(transform->outBuf);
275 inSize = xmlSecBufferGetSize(in);
276 outSize = xmlSecBufferGetSize(out);
277 xmlSecAssert2(outSize == 0, -1);
279 /* the encoded size is equal to the keys size so we could not
280 * process more than that */
281 if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) {
282 xmlSecError(XMLSEC_ERRORS_HERE,
283 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
285 XMLSEC_ERRORS_R_INVALID_SIZE,
286 "%d when expected less than %d", inSize, keySize);
288 } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) {
289 xmlSecError(XMLSEC_ERRORS_HERE,
290 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
292 XMLSEC_ERRORS_R_INVALID_SIZE,
293 "%d when expected %d", inSize, keySize);
298 ret = xmlSecBufferSetMaxSize(out, outSize);
300 xmlSecError(XMLSEC_ERRORS_HERE,
301 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
302 "xmlSecBufferSetMaxSize",
303 XMLSEC_ERRORS_R_XMLSEC_FAILED,
308 if(transform->operation == xmlSecTransformOperationEncrypt) {
309 ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in),
310 xmlSecBufferGetData(out),
311 ctx->pKey->pkey.rsa, RSA_PKCS1_PADDING);
313 xmlSecError(XMLSEC_ERRORS_HERE,
314 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
315 "RSA_public_encrypt",
316 XMLSEC_ERRORS_R_CRYPTO_FAILED,
322 ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in),
323 xmlSecBufferGetData(out),
324 ctx->pKey->pkey.rsa, RSA_PKCS1_PADDING);
326 xmlSecError(XMLSEC_ERRORS_HERE,
327 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
328 "RSA_private_decrypt",
329 XMLSEC_ERRORS_R_CRYPTO_FAILED,
336 ret = xmlSecBufferSetSize(out, outSize);
338 xmlSecError(XMLSEC_ERRORS_HERE,
339 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
340 "xmlSecBufferSetSize",
341 XMLSEC_ERRORS_R_XMLSEC_FAILED,
346 ret = xmlSecBufferRemoveHead(in, inSize);
348 xmlSecError(XMLSEC_ERRORS_HERE,
349 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
350 "xmlSecBufferRemoveHead",
351 XMLSEC_ERRORS_R_XMLSEC_FAILED,
359 /**************************************************************************
361 * Internal OpenSSL RSA OAPE CTX
363 *************************************************************************/
364 typedef struct _xmlSecOpenSSLRsaOaepCtx xmlSecOpenSSLRsaOaepCtx,
365 *xmlSecOpenSSLRsaOaepCtxPtr;
366 struct _xmlSecOpenSSLRsaOaepCtx {
368 xmlSecBuffer oaepParams;
371 /*********************************************************************
373 * RSA OAEP key transport transform
375 * xmlSecOpenSSLRsaOaepCtx is located after xmlSecTransform
377 ********************************************************************/
378 #define xmlSecOpenSSLRsaOaepSize \
379 (sizeof(xmlSecTransform) + sizeof(xmlSecOpenSSLRsaOaepCtx))
380 #define xmlSecOpenSSLRsaOaepGetCtx(transform) \
381 ((xmlSecOpenSSLRsaOaepCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
383 static int xmlSecOpenSSLRsaOaepInitialize (xmlSecTransformPtr transform);
384 static void xmlSecOpenSSLRsaOaepFinalize (xmlSecTransformPtr transform);
385 static int xmlSecOpenSSLRsaOaepNodeRead (xmlSecTransformPtr transform,
387 xmlSecTransformCtxPtr transformCtx);
388 static int xmlSecOpenSSLRsaOaepSetKeyReq (xmlSecTransformPtr transform,
389 xmlSecKeyReqPtr keyReq);
390 static int xmlSecOpenSSLRsaOaepSetKey (xmlSecTransformPtr transform,
392 static int xmlSecOpenSSLRsaOaepExecute (xmlSecTransformPtr transform,
394 xmlSecTransformCtxPtr transformCtx);
395 static int xmlSecOpenSSLRsaOaepProcess (xmlSecTransformPtr transform,
396 xmlSecTransformCtxPtr transformCtx);
398 static xmlSecTransformKlass xmlSecOpenSSLRsaOaepKlass = {
399 /* klass/object sizes */
400 sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
401 xmlSecOpenSSLRsaOaepSize, /* xmlSecSize objSize */
403 xmlSecNameRsaOaep, /* const xmlChar* name; */
404 xmlSecHrefRsaOaep, /* const xmlChar* href; */
405 xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
407 xmlSecOpenSSLRsaOaepInitialize, /* xmlSecTransformInitializeMethod initialize; */
408 xmlSecOpenSSLRsaOaepFinalize, /* xmlSecTransformFinalizeMethod finalize; */
409 xmlSecOpenSSLRsaOaepNodeRead, /* xmlSecTransformNodeReadMethod readNode; */
410 NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
411 xmlSecOpenSSLRsaOaepSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
412 xmlSecOpenSSLRsaOaepSetKey, /* xmlSecTransformSetKeyMethod setKey; */
413 NULL, /* xmlSecTransformValidateMethod validate; */
414 xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
415 xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
416 xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
417 NULL, /* xmlSecTransformPushXmlMethod pushXml; */
418 NULL, /* xmlSecTransformPopXmlMethod popXml; */
419 xmlSecOpenSSLRsaOaepExecute, /* xmlSecTransformExecuteMethod execute; */
421 NULL, /* void* reserved0; */
422 NULL, /* void* reserved1; */
426 * xmlSecOpenSSLTransformRsaOaepGetKlass:
428 * The RSA-OAEP key transport transform klass.
430 * Returns: RSA-OAEP key transport transform klass.
433 xmlSecOpenSSLTransformRsaOaepGetKlass(void) {
434 return(&xmlSecOpenSSLRsaOaepKlass);
438 xmlSecOpenSSLRsaOaepInitialize(xmlSecTransformPtr transform) {
439 xmlSecOpenSSLRsaOaepCtxPtr ctx;
442 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
443 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
445 ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
446 xmlSecAssert2(ctx != NULL, -1);
448 memset(ctx, 0, sizeof(xmlSecOpenSSLRsaOaepCtx));
450 ret = xmlSecBufferInitialize(&(ctx->oaepParams), 0);
452 xmlSecError(XMLSEC_ERRORS_HERE,
453 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
454 "xmlSecBufferInitialize",
455 XMLSEC_ERRORS_R_XMLSEC_FAILED,
456 XMLSEC_ERRORS_NO_MESSAGE);
463 xmlSecOpenSSLRsaOaepFinalize(xmlSecTransformPtr transform) {
464 xmlSecOpenSSLRsaOaepCtxPtr ctx;
466 xmlSecAssert(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId));
467 xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize));
469 ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
470 xmlSecAssert(ctx != NULL);
472 if(ctx->pKey != NULL) {
473 EVP_PKEY_free(ctx->pKey);
475 xmlSecBufferFinalize(&(ctx->oaepParams));
476 memset(ctx, 0, sizeof(xmlSecOpenSSLRsaOaepCtx));
480 xmlSecOpenSSLRsaOaepNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
481 xmlSecOpenSSLRsaOaepCtxPtr ctx;
485 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
486 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
487 xmlSecAssert2(node != NULL, -1);
488 xmlSecAssert2(transformCtx != NULL, -1);
490 ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
491 xmlSecAssert2(ctx != NULL, -1);
492 xmlSecAssert2(xmlSecBufferGetSize(&(ctx->oaepParams)) == 0, -1);
494 cur = xmlSecGetNextElementNode(node->children);
495 if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeRsaOAEPparams, xmlSecEncNs)) {
496 ret = xmlSecBufferBase64NodeContentRead(&(ctx->oaepParams), cur);
498 xmlSecError(XMLSEC_ERRORS_HERE,
499 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
500 "xmlSecBufferBase64NodeContentRead",
501 XMLSEC_ERRORS_R_XMLSEC_FAILED,
502 XMLSEC_ERRORS_NO_MESSAGE);
505 cur = xmlSecGetNextElementNode(cur->next);
508 if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeDigestMethod, xmlSecDSigNs)) {
511 /* Algorithm attribute is required */
512 algorithm = xmlGetProp(cur, xmlSecAttrAlgorithm);
513 if(algorithm == NULL) {
514 xmlSecError(XMLSEC_ERRORS_HERE,
515 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
516 xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
517 XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
519 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
523 /* for now we support only sha1 */
524 if(xmlStrcmp(algorithm, xmlSecHrefSha1) != 0) {
525 xmlSecError(XMLSEC_ERRORS_HERE,
526 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
527 xmlSecErrorsSafeString(algorithm),
528 XMLSEC_ERRORS_R_INVALID_TRANSFORM,
529 "digest algorithm is not supported for rsa/oaep");
535 cur = xmlSecGetNextElementNode(cur->next);
539 xmlSecError(XMLSEC_ERRORS_HERE,
540 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
541 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
542 XMLSEC_ERRORS_R_UNEXPECTED_NODE,
543 XMLSEC_ERRORS_NO_MESSAGE);
551 xmlSecOpenSSLRsaOaepSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
552 xmlSecOpenSSLRsaOaepCtxPtr ctx;
554 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
555 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
556 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
557 xmlSecAssert2(keyReq != NULL, -1);
559 ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
560 xmlSecAssert2(ctx != NULL, -1);
562 keyReq->keyId = xmlSecOpenSSLKeyDataRsaId;
563 if(transform->operation == xmlSecTransformOperationEncrypt) {
564 keyReq->keyType = xmlSecKeyDataTypePublic;
565 keyReq->keyUsage = xmlSecKeyUsageEncrypt;
567 keyReq->keyType = xmlSecKeyDataTypePrivate;
568 keyReq->keyUsage = xmlSecKeyUsageDecrypt;
575 xmlSecOpenSSLRsaOaepSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
576 xmlSecOpenSSLRsaOaepCtxPtr ctx;
579 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
580 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
581 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
582 xmlSecAssert2(key != NULL, -1);
583 xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecOpenSSLKeyDataRsaId), -1);
585 ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
586 xmlSecAssert2(ctx != NULL, -1);
587 xmlSecAssert2(ctx->pKey == NULL, -1);
589 pKey = xmlSecOpenSSLKeyDataRsaGetEvp(xmlSecKeyGetValue(key));
591 xmlSecError(XMLSEC_ERRORS_HERE,
592 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
593 "xmlSecOpenSSLKeyDataRsaGetEvp",
594 XMLSEC_ERRORS_R_XMLSEC_FAILED,
595 XMLSEC_ERRORS_NO_MESSAGE);
598 xmlSecAssert2(pKey->type == EVP_PKEY_RSA, -1);
599 xmlSecAssert2(pKey->pkey.rsa != NULL, -1);
601 ctx->pKey = xmlSecOpenSSLEvpKeyDup(pKey);
602 if(ctx->pKey == NULL) {
603 xmlSecError(XMLSEC_ERRORS_HERE,
604 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
605 "xmlSecOpenSSLEvpKeyDup",
606 XMLSEC_ERRORS_R_XMLSEC_FAILED,
607 XMLSEC_ERRORS_NO_MESSAGE);
615 xmlSecOpenSSLRsaOaepExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
616 xmlSecOpenSSLRsaOaepCtxPtr ctx;
619 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
620 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
621 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
622 xmlSecAssert2(transformCtx != NULL, -1);
624 ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
625 xmlSecAssert2(ctx != NULL, -1);
626 xmlSecAssert2(ctx->pKey != NULL, -1);
628 if(transform->status == xmlSecTransformStatusNone) {
629 transform->status = xmlSecTransformStatusWorking;
632 if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) {
633 /* just do nothing */
634 } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) {
635 ret = xmlSecOpenSSLRsaOaepProcess(transform, transformCtx);
637 xmlSecError(XMLSEC_ERRORS_HERE,
638 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
639 "xmlSecOpenSSLRsaOaepProcess",
640 XMLSEC_ERRORS_R_XMLSEC_FAILED,
641 XMLSEC_ERRORS_NO_MESSAGE);
644 transform->status = xmlSecTransformStatusFinished;
645 } else if(transform->status == xmlSecTransformStatusFinished) {
646 /* the only way we can get here is if there is no input */
647 xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
649 xmlSecError(XMLSEC_ERRORS_HERE,
650 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
652 XMLSEC_ERRORS_R_INVALID_STATUS,
653 "status=%d", transform->status);
660 xmlSecOpenSSLRsaOaepProcess(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) {
661 xmlSecOpenSSLRsaOaepCtxPtr ctx;
662 xmlSecSize paramsSize;
663 xmlSecBufferPtr in, out;
664 xmlSecSize inSize, outSize;
668 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
669 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
670 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
671 xmlSecAssert2(transformCtx != NULL, -1);
673 ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
674 xmlSecAssert2(ctx != NULL, -1);
675 xmlSecAssert2(ctx->pKey != NULL, -1);
676 xmlSecAssert2(ctx->pKey->type == EVP_PKEY_RSA, -1);
677 xmlSecAssert2(ctx->pKey->pkey.rsa != NULL, -1);
679 keySize = RSA_size(ctx->pKey->pkey.rsa);
680 xmlSecAssert2(keySize > 0, -1);
682 in = &(transform->inBuf);
683 out = &(transform->outBuf);
685 inSize = xmlSecBufferGetSize(in);
686 outSize = xmlSecBufferGetSize(out);
687 xmlSecAssert2(outSize == 0, -1);
689 /* the encoded size is equal to the keys size so we could not
690 * process more than that */
691 if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) {
692 xmlSecError(XMLSEC_ERRORS_HERE,
693 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
695 XMLSEC_ERRORS_R_INVALID_SIZE,
696 "%d when expected less than %d", inSize, keySize);
698 } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) {
699 xmlSecError(XMLSEC_ERRORS_HERE,
700 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
702 XMLSEC_ERRORS_R_INVALID_SIZE,
703 "%d when expected %d", inSize, keySize);
708 ret = xmlSecBufferSetMaxSize(out, outSize);
710 xmlSecError(XMLSEC_ERRORS_HERE,
711 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
712 "xmlSecBufferSetMaxSize",
713 XMLSEC_ERRORS_R_XMLSEC_FAILED,
718 paramsSize = xmlSecBufferGetSize(&(ctx->oaepParams));
719 if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize == 0)) {
720 /* encode w/o OAEPParams --> simple */
721 ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in),
722 xmlSecBufferGetData(out),
723 ctx->pKey->pkey.rsa, RSA_PKCS1_OAEP_PADDING);
725 xmlSecError(XMLSEC_ERRORS_HERE,
726 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
727 "RSA_public_encrypt(RSA_PKCS1_OAEP_PADDING)",
728 XMLSEC_ERRORS_R_CRYPTO_FAILED,
729 XMLSEC_ERRORS_NO_MESSAGE);
733 } else if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize > 0)) {
734 xmlSecAssert2(xmlSecBufferGetData(&(ctx->oaepParams)) != NULL, -1);
736 /* add space for padding */
737 ret = xmlSecBufferSetMaxSize(in, keySize);
739 xmlSecError(XMLSEC_ERRORS_HERE,
740 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
741 "xmlSecBufferSetMaxSize",
742 XMLSEC_ERRORS_R_XMLSEC_FAILED,
748 ret = RSA_padding_add_PKCS1_OAEP(xmlSecBufferGetData(in), keySize,
749 xmlSecBufferGetData(in), inSize,
750 xmlSecBufferGetData(&(ctx->oaepParams)),
753 xmlSecError(XMLSEC_ERRORS_HERE,
754 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
755 "RSA_padding_add_PKCS1_OAEP",
756 XMLSEC_ERRORS_R_CRYPTO_FAILED,
757 XMLSEC_ERRORS_NO_MESSAGE);
762 /* encode with OAEPParams */
763 ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in),
764 xmlSecBufferGetData(out),
765 ctx->pKey->pkey.rsa, RSA_NO_PADDING);
767 xmlSecError(XMLSEC_ERRORS_HERE,
768 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
769 "RSA_public_encrypt(RSA_NO_PADDING)",
770 XMLSEC_ERRORS_R_CRYPTO_FAILED,
771 XMLSEC_ERRORS_NO_MESSAGE);
775 } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize == 0)) {
776 ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in),
777 xmlSecBufferGetData(out),
778 ctx->pKey->pkey.rsa, RSA_PKCS1_OAEP_PADDING);
780 xmlSecError(XMLSEC_ERRORS_HERE,
781 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
782 "RSA_private_decrypt(RSA_PKCS1_OAEP_PADDING)",
783 XMLSEC_ERRORS_R_CRYPTO_FAILED,
784 XMLSEC_ERRORS_NO_MESSAGE);
788 } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize != 0)) {
791 ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in),
792 xmlSecBufferGetData(out),
793 ctx->pKey->pkey.rsa, RSA_NO_PADDING);
795 xmlSecError(XMLSEC_ERRORS_HERE,
796 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
797 "RSA_private_decrypt(RSA_NO_PADDING)",
798 XMLSEC_ERRORS_R_CRYPTO_FAILED,
799 XMLSEC_ERRORS_NO_MESSAGE);
805 * the private decrypt w/o padding adds '0's at the begginning.
806 * it's not clear for me can I simply skip all '0's from the
807 * beggining so I have to do decode it back to BIGNUM and dump
811 if(BN_bin2bn(xmlSecBufferGetData(out), outSize, &bn) == NULL) {
812 xmlSecError(XMLSEC_ERRORS_HERE,
813 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
815 XMLSEC_ERRORS_R_CRYPTO_FAILED,
821 ret = BN_bn2bin(&bn, xmlSecBufferGetData(out));
823 xmlSecError(XMLSEC_ERRORS_HERE,
824 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
826 XMLSEC_ERRORS_R_CRYPTO_FAILED,
827 XMLSEC_ERRORS_NO_MESSAGE);
834 ret = RSA_padding_check_PKCS1_OAEP(xmlSecBufferGetData(out), outSize,
835 xmlSecBufferGetData(out), outSize,
837 xmlSecBufferGetData(&(ctx->oaepParams)),
840 xmlSecError(XMLSEC_ERRORS_HERE,
841 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
842 "RSA_padding_check_PKCS1_OAEP",
843 XMLSEC_ERRORS_R_CRYPTO_FAILED,
844 XMLSEC_ERRORS_NO_MESSAGE);
849 xmlSecAssert2("we could not be here" == NULL, -1);
853 ret = xmlSecBufferSetSize(out, outSize);
855 xmlSecError(XMLSEC_ERRORS_HERE,
856 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
857 "xmlSecBufferSetSize",
858 XMLSEC_ERRORS_R_XMLSEC_FAILED,
863 ret = xmlSecBufferRemoveHead(in, inSize);
865 xmlSecError(XMLSEC_ERRORS_HERE,
866 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
867 "xmlSecBufferRemoveHead",
868 XMLSEC_ERRORS_R_XMLSEC_FAILED,
876 #endif /* XMLSEC_NO_RSA */