/
githubmirror
/
xmlsec
Обзор
Документация
Войти
/
githubmirror
/
xmlsec
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/nss/keytrans.c
946 строк
34 KB
lsh123
(xmlsec-nss) Added SHA3 support (#1139)
22 апр 2026, 05:22
Не верифицирован
22 апр 2026, 05:22
6fa8ffb
Код
Авторство
О чём код?
/** * XML Security Library (http://www.aleksey.com/xmlsec). * * This is free software; see the Copyright file in the source distribution for precise wording. * * Copyright (C) 2003-2026 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. * Copyright (c) 2003 America Online, Inc. All rights reserved. */ /** * @addtogroup xmlsec_nss_crypto * @brief RSA Key Transport transforms implementation for NSS. */ #include "globals.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <nss.h> #include <pk11pub.h> #include <keyhi.h> #include <hasht.h> #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/private.h> #include <xmlsec/transforms.h> #include <xmlsec/errors.h> #include <xmlsec/nss/crypto.h> #include <xmlsec/nss/pkikeys.h> #include "../cast_helpers.h" #include "../transform_helpers.h" /****************************************************************************** * * Key transport transforms context * *****************************************************************************/ typedef struct _xmlSecNssKeyTransportCtx xmlSecNssKeyTransportCtx; typedef struct _xmlSecNssKeyTransportCtx* xmlSecNssKeyTransportCtxPtr; struct _xmlSecNssKeyTransportCtx { CK_MECHANISM_TYPE cipher; SECKEYPublicKey* pubkey; SECKEYPrivateKey* prikey; xmlSecKeyDataId keyId; xmlSecBufferPtr material; /* to be encrypted/decrypted material */ #ifndef XMLSEC_NO_RSA_OAEP /* RSA OAEP */ CK_MECHANISM_TYPE oaepHashAlg; CK_RSA_PKCS_MGF_TYPE oaepMgf; xmlSecBuffer oaepParams; #endif /* XMLSEC_NO_RSA_OAEP */ }; /****************************************************************************** * * Key transport transform * *****************************************************************************/ XMLSEC_TRANSFORM_DECLARE(NssKeyTransport, xmlSecNssKeyTransportCtx) #define xmlSecNssKeyTransportSize XMLSEC_TRANSFORM_SIZE(NssKeyTransport) static int xmlSecNssKeyTransportInitialize (xmlSecTransformPtr transform); static void xmlSecNssKeyTransportFinalize (xmlSecTransformPtr transform); static int xmlSecNssKeyTransportSetKeyReq (xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq); static int xmlSecNssKeyTransportSetKey (xmlSecTransformPtr transform, xmlSecKeyPtr key); static int xmlSecNssKeyTransportExecute (xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx); static int xmlSecNssKeyTransportCheckId(xmlSecTransformPtr transform) { #ifndef XMLSEC_NO_RSA #ifndef XMLSEC_NO_RSA_PKCS15 if(xmlSecTransformCheckId(transform, xmlSecNssTransformRsaPkcs1Id)) { return(1); } #endif /* XMLSEC_NO_RSA_PKCS15 */ #ifndef XMLSEC_NO_RSA_OAEP if(xmlSecTransformCheckId(transform, xmlSecNssTransformRsaOaepId)) { return (1); } if(xmlSecTransformCheckId(transform, xmlSecNssTransformRsaOaepEnc11Id)) { return (1); } #endif /* XMLSEC_NO_RSA_OAEP */ #endif /* XMLSEC_NO_RSA */ /* not found */ return(0); } static int xmlSecNssKeyTransportInitialize(xmlSecTransformPtr transform) { xmlSecNssKeyTransportCtxPtr context; #ifndef XMLSEC_NO_RSA_OAEP int ret; #endif /* XMLSEC_NO_RSA_OAEP */ xmlSecAssert2(xmlSecNssKeyTransportCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKeyTransportSize), -1); context = xmlSecNssKeyTransportGetCtx(transform); xmlSecAssert2(context != NULL, -1); /* initialize context */ memset(context, 0, sizeof(xmlSecNssKeyTransportCtx)); #ifndef XMLSEC_NO_RSA #ifndef XMLSEC_NO_RSA_PKCS15 if(transform->id == xmlSecNssTransformRsaPkcs1Id) { context->cipher = CKM_RSA_PKCS; context->keyId = xmlSecNssKeyDataRsaId; } else #endif /* XMLSEC_NO_RSA_PKCS15 */ #ifndef XMLSEC_NO_RSA_OAEP if(transform->id == xmlSecNssTransformRsaOaepId) { context->cipher = CKM_RSA_PKCS_OAEP; context->keyId = xmlSecNssKeyDataRsaId; } else if(transform->id == xmlSecNssTransformRsaOaepEnc11Id) { context->cipher = CKM_RSA_PKCS_OAEP; context->keyId = xmlSecNssKeyDataRsaId; } else #endif /* XMLSEC_NO_RSA_OAEP */ #endif /* XMLSEC_NO_RSA */ /* not found */ { xmlSecInvalidTransfromError(transform); return(-1); } #ifndef XMLSEC_NO_RSA_OAEP ret = xmlSecBufferInitialize(&(context->oaepParams), 0); if(ret < 0) { xmlSecInternalError("xmlSecBufferInitialize", xmlSecTransformGetName(transform)); return(-1); } #endif /* XMLSEC_NO_RSA_OAEP */ return(0); } static void xmlSecNssKeyTransportFinalize(xmlSecTransformPtr transform) { xmlSecNssKeyTransportCtxPtr context; xmlSecAssert(xmlSecNssKeyTransportCheckId(transform)); xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecNssKeyTransportSize)); context = xmlSecNssKeyTransportGetCtx(transform); xmlSecAssert(context != NULL); if(context->pubkey != NULL) { SECKEY_DestroyPublicKey(context->pubkey); context->pubkey = NULL; } if(context->prikey != NULL) { SECKEY_DestroyPrivateKey(context->prikey); context->prikey = NULL; } if(context->material != NULL) { xmlSecBufferDestroy(context->material); context->material = NULL; } #ifndef XMLSEC_NO_RSA_OAEP xmlSecBufferFinalize(&(context->oaepParams)); #endif /* XMLSEC_NO_RSA_OAEP */ } static int xmlSecNssKeyTransportSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) { xmlSecNssKeyTransportCtxPtr context; xmlSecAssert2(xmlSecNssKeyTransportCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKeyTransportSize), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(keyReq != NULL, -1); context = xmlSecNssKeyTransportGetCtx(transform); xmlSecAssert2(context != NULL, -1); keyReq->keyId = context->keyId; if(transform->operation == xmlSecTransformOperationEncrypt) { keyReq->keyUsage = xmlSecKeyUsageEncrypt; keyReq->keyType = xmlSecKeyDataTypePublic; } else { keyReq->keyUsage = xmlSecKeyUsageDecrypt; keyReq->keyType = xmlSecKeyDataTypePrivate; } return(0); } static int xmlSecNssKeyTransportSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecNssKeyTransportCtxPtr context = NULL; xmlSecKeyDataPtr keyData = NULL; SECKEYPublicKey* pubkey = NULL; SECKEYPrivateKey* prikey = NULL; xmlSecAssert2(xmlSecNssKeyTransportCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKeyTransportSize), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(key != NULL, -1); context = xmlSecNssKeyTransportGetCtx(transform); if((context == NULL) || (context->keyId == NULL) || (context->pubkey != NULL)) { xmlSecInternalError("xmlSecNssKeyTransportGetCtx", xmlSecTransformGetName(transform)); return(-1); } xmlSecAssert2(xmlSecKeyCheckId(key, context->keyId), -1); keyData = xmlSecKeyGetValue(key); if(keyData == NULL) { xmlSecInternalError("xmlSecKeyGetValue", xmlSecTransformGetName(transform)); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { pubkey = xmlSecNssPKIKeyDataGetPubKey(keyData); if(pubkey == NULL) { xmlSecInternalError("xmlSecNssPKIKeyDataGetPubKey", xmlSecKeyDataGetName(keyData)); return(-1); } context->pubkey = pubkey; } else { prikey = xmlSecNssPKIKeyDataGetPrivKey(keyData); if(prikey == NULL) { xmlSecInternalError("xmlSecNssPKIKeyDataGetPrivKey", xmlSecKeyDataGetName(keyData)); return(-1); } context->prikey = prikey; } /* done */ return(0); } static int xmlSecNssKeyTransportCtxInit(xmlSecNssKeyTransportCtxPtr ctx, xmlSecBufferPtr in, xmlSecBufferPtr out, int encrypt, xmlSecTransformCtxPtr transformCtx) { xmlSecSize blockSize; xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->cipher != CKM_INVALID_MECHANISM, -1); xmlSecAssert2((ctx->pubkey != NULL && encrypt) || (ctx->prikey != NULL && !encrypt), -1); xmlSecAssert2(ctx->keyId != NULL, -1); xmlSecAssert2(in != NULL, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); if(ctx->material != NULL) { xmlSecBufferDestroy(ctx->material); ctx->material = NULL; } if(ctx->pubkey != NULL) { blockSize = SECKEY_PublicKeyStrength(ctx->pubkey); if(blockSize <= 0) { xmlSecNssError("SECKEY_PublicKeyStrength", NULL); return(-1); } } else if(ctx->prikey != NULL) { int blockLen; blockLen = PK11_SignatureLen(ctx->prikey); if(blockLen <= 0) { xmlSecNssError("PK11_SignatureLen", NULL); return(-1); } XMLSEC_SAFE_CAST_INT_TO_SIZE(blockLen, blockSize, return(-1), NULL); } else { xmlSecOtherError(XMLSEC_ERRORS_R_KEY_NOT_FOUND, NULL, "neither public or private keys are set"); return(-1); } ctx->material = xmlSecBufferCreate(blockSize); if(ctx->material == NULL) { xmlSecInternalError2("xmlSecBufferSetData", NULL, "size=" XMLSEC_SIZE_FMT, blockSize); return(-1); } /* read raw key material into context */ if(xmlSecBufferSetData(ctx->material, xmlSecBufferGetData(in), xmlSecBufferGetSize(in)) < 0) { xmlSecInternalError2("xmlSecBufferSetData", NULL, "size=" XMLSEC_SIZE_FMT, xmlSecBufferGetSize(in)); return(-1); } if(xmlSecBufferRemoveHead(in, xmlSecBufferGetSize(in)) < 0) { xmlSecInternalError2("xmlSecBufferRemoveHead", NULL, "size=" XMLSEC_SIZE_FMT, xmlSecBufferGetSize(in)); return(-1); } return(0); } static int xmlSecNssKeyTransportCtxUpdate(xmlSecNssKeyTransportCtxPtr ctx, xmlSecBufferPtr in, xmlSecBufferPtr out, int encrypt, xmlSecTransformCtxPtr transformCtx) { xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->cipher != CKM_INVALID_MECHANISM, -1); xmlSecAssert2((ctx->pubkey != NULL && encrypt) || (ctx->prikey != NULL && !encrypt), -1); xmlSecAssert2(ctx->keyId != NULL, -1); xmlSecAssert2(ctx->material != NULL, -1); xmlSecAssert2(in != NULL, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); /* read raw key material and append into context */ if(xmlSecBufferAppend(ctx->material, xmlSecBufferGetData(in), xmlSecBufferGetSize(in)) < 0) { xmlSecInternalError2("xmlSecBufferAppend", NULL, "size=" XMLSEC_SIZE_FMT, xmlSecBufferGetSize(in)); return(-1); } if(xmlSecBufferRemoveHead(in, xmlSecBufferGetSize(in)) < 0) { xmlSecInternalError2("xmlSecBufferRemoveHead", NULL, "size=" XMLSEC_SIZE_FMT, xmlSecBufferGetSize(in)); return(-1); } return(0); } #ifndef XMLSEC_NO_RSA_OAEP static int xmlSecNssKeyTransportSetOaepParams(xmlSecNssKeyTransportCtxPtr ctx, CK_RSA_PKCS_OAEP_PARAMS* oaepParams) { xmlSecSize size; xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(oaepParams != NULL, -1); oaepParams->hashAlg = ctx->oaepHashAlg; oaepParams->mgf = ctx->oaepMgf ; oaepParams->source = CKZ_DATA_SPECIFIED; oaepParams->pSourceData = xmlSecBufferGetData(&(ctx->oaepParams)); size = xmlSecBufferGetSize(&(ctx->oaepParams)); XMLSEC_SAFE_CAST_SIZE_TO_ULONG(size, oaepParams->ulSourceDataLen, return(-1), NULL); return(0); } #endif /* XMLSEC_NO_RSA_OAEP */ static PK11SymKey* xmlSecNssKeyTransportLoadSymKeyUsingPublicKeySlot(xmlSecNssKeyTransportCtxPtr ctx, SECItem* oriskv) { PK11SlotInfo* slot = NULL; PK11SymKey* symKey = NULL; CK_OBJECT_HANDLE id; xmlSecAssert2(ctx != NULL, NULL); xmlSecAssert2(ctx->pubkey != NULL, NULL); xmlSecAssert2(oriskv != NULL, NULL); if(ctx->pubkey->pkcs11Slot == NULL) { slot = PK11_GetBestSlot(ctx->cipher, NULL); if(slot == NULL) { xmlSecNssError("PK11_GetBestSlot", NULL); return(NULL); } id = PK11_ImportPublicKey(slot, ctx->pubkey, PR_FALSE); if(id == CK_INVALID_HANDLE) { xmlSecNssError("PK11_ImportPublicKey", NULL); PK11_FreeSlot(slot); return(NULL); } } /* pay attention to mechanism */ symKey = PK11_ImportSymKey( ctx->pubkey->pkcs11Slot != NULL ? ctx->pubkey->pkcs11Slot : slot, ctx->cipher, PK11_OriginUnwrap, CKA_WRAP, oriskv, NULL); if(symKey == NULL) { xmlSecNssError("PK11_ImportSymKey", NULL); PK11_FreeSlot(slot); return(NULL); } PK11_FreeSlot(slot); return(symKey); } static int xmlSecNssKeyTransportCtxFinal(xmlSecNssKeyTransportCtxPtr ctx, xmlSecBufferPtr in, xmlSecBufferPtr out, int encrypt, xmlSecTransformCtxPtr transformCtx) { PK11SymKey* symKey = NULL; SECItem oriskv = { siBuffer, NULL, 0 }; xmlSecSize blockSize, materialSize, resultSize; unsigned int resultLen; xmlSecBufferPtr result; SECStatus rv; int res = -1; xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->cipher != CKM_INVALID_MECHANISM, -1); xmlSecAssert2((ctx->pubkey != NULL && encrypt) || (ctx->prikey != NULL && !encrypt), -1); xmlSecAssert2(ctx->keyId != NULL, -1); xmlSecAssert2(ctx->material != NULL, -1); xmlSecAssert2(in != NULL, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); /* read raw key material and append into context */ if(xmlSecBufferAppend(ctx->material, xmlSecBufferGetData(in), xmlSecBufferGetSize(in)) < 0) { xmlSecInternalError2("xmlSecBufferAppend", NULL, "size=" XMLSEC_SIZE_FMT, xmlSecBufferGetSize(in)); return(-1); } materialSize = xmlSecBufferGetSize(ctx->material); if(xmlSecBufferRemoveHead(in, xmlSecBufferGetSize(in)) < 0) { xmlSecInternalError2("xmlSecBufferRemoveHead", NULL, "size=" XMLSEC_SIZE_FMT, xmlSecBufferGetSize(in)); return(-1); } /* Now we get all of the key material */ /* from now on we will wrap or unwrap the key */ if(ctx->pubkey != NULL) { blockSize = SECKEY_PublicKeyStrength(ctx->pubkey); if(blockSize <= 0) { xmlSecNssError("SECKEY_PublicKeyStrength", NULL); return(-1); } } else if(ctx->prikey != NULL) { int blockLen; blockLen = PK11_SignatureLen(ctx->prikey); if(blockLen <= 0) { xmlSecNssError("PK11_SignatureLen", NULL); return(-1); } XMLSEC_SAFE_CAST_INT_TO_SIZE(blockLen, blockSize, return(-1), NULL); } else { xmlSecOtherError(XMLSEC_ERRORS_R_KEY_NOT_FOUND, NULL, "neither public or private keys are set"); return(-1); } result = xmlSecBufferCreate(blockSize * 2); if(result == NULL) { xmlSecInternalError("xmlSecBufferCreate", NULL); return(-1); } resultSize = xmlSecBufferGetMaxSize(result); XMLSEC_SAFE_CAST_SIZE_TO_UINT(resultSize, resultLen, goto done, NULL); oriskv.type = siBuffer; oriskv.data = xmlSecBufferGetData(ctx->material); XMLSEC_SAFE_CAST_SIZE_TO_UINT(materialSize, oriskv.len, goto done, NULL); if(encrypt != 0) { SECItem wrpskv = { siBuffer, NULL, 0 }; /* Create template symmetric key from material if needed */ symKey = xmlSecNssKeyTransportLoadSymKeyUsingPublicKeySlot(ctx, &oriskv); if (symKey == NULL) { xmlSecInternalError("xmlSecNssKeyTransportLoadSymKeyFromPublicKey", NULL); goto done; } wrpskv.type = siBuffer; wrpskv.data = xmlSecBufferGetData(result); wrpskv.len = resultLen; if(ctx->cipher == CKM_RSA_PKCS) { rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, ctx->pubkey, symKey, &wrpskv); if (rv != SECSuccess) { xmlSecNssError("PK11_PubWrapSymKey", NULL); goto done; } } else #ifndef XMLSEC_NO_RSA_OAEP if(ctx->cipher == CKM_RSA_PKCS_OAEP) { CK_RSA_PKCS_OAEP_PARAMS oaep_params; SECItem param = {siBuffer, (unsigned char*)&oaep_params, sizeof(oaep_params)}; int ret; ret = xmlSecNssKeyTransportSetOaepParams(ctx, &oaep_params); if (ret < 0) { xmlSecInternalError("xmlSecNssKeyTransportSetOaepParams", NULL); goto done; } rv = PK11_PubWrapSymKeyWithMechanism(ctx->pubkey, CKM_RSA_PKCS_OAEP, ¶m, symKey, &wrpskv); if (rv != SECSuccess) { xmlSecNssError("PK11_PubWrapSymKeyWithMechanism", NULL); goto done; } } else #endif /* XMLSEC_NO_RSA_OAEP */ { xmlSecInvalidTypeError("Invalid keywrap algorithm", NULL); goto done; } if(xmlSecBufferSetSize(result, wrpskv.len) < 0) { xmlSecInternalError2("xmlSecBufferSetSize", NULL, "size=%u", wrpskv.len); goto done; } } else { SECItem* keyItem; /* pay attention to mechanism */ if(ctx->cipher == CKM_RSA_PKCS) { symKey = PK11_PubUnwrapSymKey(ctx->prikey, &oriskv, CKM_RSA_PKCS, CKA_UNWRAP, 0); if(symKey == NULL) { xmlSecNssError("PK11_PubUnwrapSymKey", NULL); goto done; } } else #ifndef XMLSEC_NO_RSA_OAEP if(ctx->cipher == CKM_RSA_PKCS_OAEP) { CK_RSA_PKCS_OAEP_PARAMS oaep_params; SECItem param = {siBuffer, (unsigned char*)&oaep_params, sizeof(oaep_params)}; int ret; ret = xmlSecNssKeyTransportSetOaepParams(ctx, &oaep_params); if (ret < 0) { xmlSecInternalError("xmlSecNssKeyTransportSetOaepParams", NULL); goto done; } symKey = PK11_PubUnwrapSymKeyWithMechanism(ctx->prikey, CKM_RSA_PKCS_OAEP, ¶m, &oriskv, 0, CKA_UNWRAP, 0); if(symKey == NULL) { xmlSecNssError("PK11_PubUnwrapSymKeyWithMechanism", NULL); goto done; } } else #endif /* XMLSEC_NO_RSA_OAEP */ { xmlSecInvalidTypeError("Invalid keywrap algorithm", NULL); goto done; } /* Extract raw data from symmetric key */ if(PK11_ExtractKeyValue(symKey) != SECSuccess) { xmlSecNssError("PK11_ExtractKeyValue", NULL); goto done; } keyItem = PK11_GetKeyData(symKey); if(keyItem == NULL) { xmlSecNssError("PK11_GetKeyData", NULL); goto done; } if(xmlSecBufferSetData(result, keyItem->data, keyItem->len) < 0) { xmlSecInternalError2("xmlSecBufferSetData", NULL, "size=%u", keyItem->len); goto done; } } /* Write output */ if(xmlSecBufferAppend(out, xmlSecBufferGetData(result), xmlSecBufferGetSize(result)) < 0) { xmlSecInternalError2("xmlSecBufferAppend", NULL, "size=" XMLSEC_SIZE_FMT, xmlSecBufferGetSize(result)); goto done; } /* success */ res = 0; done: /* cleanup*/ xmlSecBufferDestroy(result); if(symKey != NULL) { PK11_FreeSymKey(symKey); } return(res); } static int xmlSecNssKeyTransportExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecNssKeyTransportCtxPtr context = NULL; xmlSecBufferPtr inBuf, outBuf; int operation; int rtv; xmlSecAssert2(xmlSecNssKeyTransportCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKeyTransportSize), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(transformCtx != NULL, -1); context = xmlSecNssKeyTransportGetCtx(transform); if(context == NULL) { xmlSecInternalError("xmlSecNssKeyTransportGetCtx", xmlSecTransformGetName(transform)); return(-1); } inBuf = &(transform->inBuf); outBuf = &(transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } operation = (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0; if(transform->status == xmlSecTransformStatusWorking) { if(context->material == NULL) { rtv = xmlSecNssKeyTransportCtxInit(context, inBuf, outBuf, operation, transformCtx); if(rtv < 0) { xmlSecInternalError("xmlSecNssKeyTransportCtxInit", xmlSecTransformGetName(transform)); return(-1); } } if((context->material == NULL) && (last != 0)) { xmlSecInvalidTransfromStatusError2(transform, "No enough data to initialize transform"); return(-1); } if(context->material != NULL) { rtv = xmlSecNssKeyTransportCtxUpdate(context, inBuf, outBuf, operation, transformCtx); if(rtv < 0) { xmlSecInternalError("xmlSecNssKeyTransportCtxUpdate", xmlSecTransformGetName(transform)); return(-1); } } if(last) { rtv = xmlSecNssKeyTransportCtxFinal(context, inBuf, outBuf, operation, transformCtx); if(rtv < 0) { xmlSecInternalError("xmlSecNssKeyTransportCtxFinal", xmlSecTransformGetName(transform)); return(-1); } transform->status = xmlSecTransformStatusFinished; } } else if(transform->status == xmlSecTransformStatusFinished) { if(xmlSecBufferGetSize(inBuf) != 0) { xmlSecInvalidTransfromStatusError2(transform, "More data available in the input buffer"); return(-1); } } else { xmlSecInvalidTransfromStatusError(transform); return(-1); } return(0); } #ifndef XMLSEC_NO_RSA #ifndef XMLSEC_NO_RSA_PKCS15 static xmlSecTransformKlass xmlSecNssRsaPkcs1Klass = { /* klass/object sizes */ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ xmlSecNssKeyTransportSize, /* xmlSecSize objSize */ xmlSecNameRsaPkcs1, /* const xmlChar* name; */ xmlSecHrefRsaPkcs1, /* const xmlChar* href; */ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ xmlSecNssKeyTransportInitialize, /* xmlSecTransformInitializeMethod initialize; */ xmlSecNssKeyTransportFinalize, /* xmlSecTransformFinalizeMethod finalize; */ NULL, /* xmlSecTransformNodeReadMethod readNode; */ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ xmlSecNssKeyTransportSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ xmlSecNssKeyTransportSetKey, /* xmlSecTransformSetKeyMethod setKey; */ NULL, /* xmlSecTransformValidateMethod validate; */ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ NULL, /* xmlSecTransformPushXmlMethod pushXml; */ NULL, /* xmlSecTransformPopXmlMethod popXml; */ xmlSecNssKeyTransportExecute, /* xmlSecTransformExecuteMethod execute; */ NULL, /* void* reserved0; */ NULL, /* void* reserved1; */ }; /** * @brief The RSA-PKCS1 key transport transform klass. * @return RSA-PKCS1 key transport transform klass. */ xmlSecTransformId xmlSecNssTransformRsaPkcs1GetKlass(void) { return(&xmlSecNssRsaPkcs1Klass); } #endif /* XMLSEC_NO_RSA_PKCS15 */ #ifndef XMLSEC_NO_RSA_OAEP static int xmlSecNssRsaOaepNodeRead (xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx); static xmlSecTransformKlass xmlSecNssRsaOaepKlass = { /* klass/object sizes */ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ xmlSecNssKeyTransportSize, /* xmlSecSize objSize */ xmlSecNameRsaOaep, /* const xmlChar* name; */ xmlSecHrefRsaOaep, /* const xmlChar* href; */ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ xmlSecNssKeyTransportInitialize, /* xmlSecTransformInitializeMethod initialize; */ xmlSecNssKeyTransportFinalize, /* xmlSecTransformFinalizeMethod finalize; */ xmlSecNssRsaOaepNodeRead, /* xmlSecTransformNodeReadMethod readNode; */ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ xmlSecNssKeyTransportSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ xmlSecNssKeyTransportSetKey, /* xmlSecTransformSetKeyMethod setKey; */ NULL, /* xmlSecTransformValidateMethod validate; */ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ NULL, /* xmlSecTransformPushXmlMethod pushXml; */ NULL, /* xmlSecTransformPopXmlMethod popXml; */ xmlSecNssKeyTransportExecute, /* xmlSecTransformExecuteMethod execute; */ NULL, /* void* reserved0; */ NULL, /* void* reserved1; */ }; /** * @brief RSA-PKCS1 key transport klass for XMLEnc 1.0. * @details The RSA-PKCS1 key transport transform klass (XMLEnc 1.0). * @return RSA-PKCS1 key transport transform klass. */ xmlSecTransformId xmlSecNssTransformRsaOaepGetKlass(void) { return(&xmlSecNssRsaOaepKlass); } static xmlSecTransformKlass xmlSecNssRsaOaepEnc11Klass = { /* klass/object sizes */ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ xmlSecNssKeyTransportSize, /* xmlSecSize objSize */ xmlSecNameRsaOaepEnc11, /* const xmlChar* name; */ xmlSecHrefRsaOaepEnc11, /* const xmlChar* href; */ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ xmlSecNssKeyTransportInitialize, /* xmlSecTransformInitializeMethod initialize; */ xmlSecNssKeyTransportFinalize, /* xmlSecTransformFinalizeMethod finalize; */ xmlSecNssRsaOaepNodeRead, /* xmlSecTransformNodeReadMethod readNode; */ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ xmlSecNssKeyTransportSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ xmlSecNssKeyTransportSetKey, /* xmlSecTransformSetKeyMethod setKey; */ NULL, /* xmlSecTransformValidateMethod validate; */ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ NULL, /* xmlSecTransformPushXmlMethod pushXml; */ NULL, /* xmlSecTransformPopXmlMethod popXml; */ xmlSecNssKeyTransportExecute, /* xmlSecTransformExecuteMethod execute; */ NULL, /* void* reserved0; */ NULL, /* void* reserved1; */ }; /** * @brief RSA-PKCS1 key transport klass for XMLEnc 1.1. * @details The RSA-PKCS1 key transport transform klass (XMLEnc 1.1). * @return RSA-PKCS1 key transport transform klass. */ xmlSecTransformId xmlSecNssTransformRsaOaepEnc11GetKlass(void) { return(&xmlSecNssRsaOaepEnc11Klass); } static int xmlSecNssRsaOaepNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx XMLSEC_ATTRIBUTE_UNUSED) { xmlSecNssKeyTransportCtxPtr ctx; xmlSecTransformRsaOaepParams oaepParams; int ret; xmlSecAssert2(xmlSecNssKeyTransportCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKeyTransportSize), -1); xmlSecAssert2(node != NULL, -1); UNREFERENCED_PARAMETER(transformCtx); ctx = xmlSecNssKeyTransportGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); ret = xmlSecTransformRsaOaepParamsInitialize(&oaepParams); if (ret < 0) { xmlSecInternalError("xmlSecTransformRsaOaepParamsInitialize", xmlSecTransformGetName(transform)); return(-1); } ret = xmlSecTransformRsaOaepParamsRead(&oaepParams, node); if (ret < 0) { xmlSecInternalError("xmlSecTransformRsaOaepParamsRead", xmlSecTransformGetName(transform)); xmlSecTransformRsaOaepParamsFinalize(&oaepParams); return(-1); } /* digest algorithm */ if (oaepParams.digestAlgorithm == NULL) { #ifndef XMLSEC_NO_SHA1 ctx->oaepHashAlg = CKM_SHA_1; #else /* XMLSEC_NO_SHA1 */ xmlSecOtherError(XMLSEC_ERRORS_R_DISABLED, NULL, "No OAEP digest algorithm is specified and the default SHA1 digest is disabled"); xmlSecTransformRsaOaepParamsFinalize(&oaepParams); return(-1); #endif /* XMLSEC_NO_SHA1 */ } else #ifndef XMLSEC_NO_SHA1 if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha1) == 0) { ctx->oaepHashAlg = CKM_SHA_1; } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA224 if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha224) == 0) { ctx->oaepHashAlg = CKM_SHA224; } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA256 if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha256) == 0) { ctx->oaepHashAlg = CKM_SHA256; } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha384) == 0) { ctx->oaepHashAlg = CKM_SHA384; } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha512) == 0) { ctx->oaepHashAlg = CKM_SHA512; } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA3 if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha3_224) == 0) { ctx->oaepHashAlg = CKM_SHA3_224; } else if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha3_256) == 0) { ctx->oaepHashAlg = CKM_SHA3_256; } else if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha3_384) == 0) { ctx->oaepHashAlg = CKM_SHA3_384; } else if (xmlStrcmp(oaepParams.digestAlgorithm, xmlSecHrefSha3_512) == 0) { ctx->oaepHashAlg = CKM_SHA3_512; } else #endif /* XMLSEC_NO_SHA3 */ { xmlSecInvalidTransfromError2(transform, "digest algorithm=\"%s\" is not supported for rsa/oaep", xmlSecErrorsSafeString(oaepParams.digestAlgorithm)); xmlSecTransformRsaOaepParamsFinalize(&oaepParams); return(-1); } /* mgf1 algorithm */ if (oaepParams.mgf1DigestAlgorithm == NULL) { #ifndef XMLSEC_NO_SHA1 ctx->oaepMgf = CKG_MGF1_SHA1; #else /* XMLSEC_NO_SHA1 */ xmlSecOtherError(XMLSEC_ERRORS_R_DISABLED, NULL, "No OAEP mgf1 digest algorithm is specified and the default SHA1 digest is disabled"); xmlSecTransformRsaOaepParamsFinalize(&oaepParams); return(-1); #endif /* XMLSEC_NO_SHA1 */ } else #ifndef XMLSEC_NO_SHA1 if (xmlStrcmp(oaepParams.mgf1DigestAlgorithm, xmlSecHrefMgf1Sha1) == 0) { ctx->oaepMgf = CKG_MGF1_SHA1; } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA224 if (xmlStrcmp(oaepParams.mgf1DigestAlgorithm, xmlSecHrefMgf1Sha224) == 0) { ctx->oaepMgf = CKG_MGF1_SHA224; } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA256 if (xmlStrcmp(oaepParams.mgf1DigestAlgorithm, xmlSecHrefMgf1Sha256) == 0) { ctx->oaepMgf = CKG_MGF1_SHA256; } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if (xmlStrcmp(oaepParams.mgf1DigestAlgorithm, xmlSecHrefMgf1Sha384) == 0) { ctx->oaepMgf = CKG_MGF1_SHA384; } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if (xmlStrcmp(oaepParams.mgf1DigestAlgorithm, xmlSecHrefMgf1Sha512) == 0) { ctx->oaepMgf = CKG_MGF1_SHA512; } else #endif /* XMLSEC_NO_SHA512 */ { xmlSecInvalidTransfromError2(transform, "mgf1 digest algorithm=\"%s\" is not supported for rsa/oaep", xmlSecErrorsSafeString(oaepParams.mgf1DigestAlgorithm)); xmlSecTransformRsaOaepParamsFinalize(&oaepParams); return(-1); } /* put oaep params buffer into ctx */ xmlSecBufferSwap(&(oaepParams.oaepParams), &(ctx->oaepParams)); /* cleanup */ xmlSecTransformRsaOaepParamsFinalize(&oaepParams); return(0); } #endif /* XMLSEC_NO_RSA_OAEP */ #endif /* XMLSEC_NO_RSA */