1134 lines
39 KiB
Diff
1134 lines
39 KiB
Diff
--- misc/xmlsec1-1.2.14/src/nss/ciphers.c 2009-09-10 05:16:27.000000000 -0400
|
|
+++ misc/build/xmlsec1-1.2.14/src/nss/ciphers.c 2009-09-10 06:59:39.000000000 -0400
|
|
@@ -11,180 +11,421 @@
|
|
|
|
#include <string.h>
|
|
|
|
-#include <nspr.h>
|
|
#include <nss.h>
|
|
-#include <secoid.h>
|
|
#include <pk11func.h>
|
|
|
|
#include <xmlsec/xmlsec.h>
|
|
+#include <xmlsec/xmltree.h>
|
|
+#include <xmlsec/base64.h>
|
|
#include <xmlsec/keys.h>
|
|
#include <xmlsec/transforms.h>
|
|
#include <xmlsec/errors.h>
|
|
|
|
#include <xmlsec/nss/crypto.h>
|
|
-
|
|
-#define XMLSEC_NSS_MAX_KEY_SIZE 32
|
|
-#define XMLSEC_NSS_MAX_IV_SIZE 32
|
|
-#define XMLSEC_NSS_MAX_BLOCK_SIZE 32
|
|
+#include <xmlsec/nss/ciphers.h>
|
|
|
|
/**************************************************************************
|
|
*
|
|
- * Internal Nss Block cipher CTX
|
|
+ * Internal Nss Block Cipher Context
|
|
+ * This context is designed for repositing a block cipher for transform
|
|
*
|
|
*****************************************************************************/
|
|
-typedef struct _xmlSecNssBlockCipherCtx xmlSecNssBlockCipherCtx,
|
|
- *xmlSecNssBlockCipherCtxPtr;
|
|
+typedef struct _xmlSecNssBlockCipherCtx xmlSecNssBlockCipherCtx ;
|
|
+typedef struct _xmlSecNssBlockCipherCtx* xmlSecNssBlockCipherCtxPtr ;
|
|
+
|
|
struct _xmlSecNssBlockCipherCtx {
|
|
CK_MECHANISM_TYPE cipher;
|
|
+ PK11SymKey* symkey ;
|
|
PK11Context* cipherCtx;
|
|
xmlSecKeyDataId keyId;
|
|
- int keyInitialized;
|
|
- int ctxInitialized;
|
|
- xmlSecByte key[XMLSEC_NSS_MAX_KEY_SIZE];
|
|
- xmlSecSize keySize;
|
|
- xmlSecByte iv[XMLSEC_NSS_MAX_IV_SIZE];
|
|
- xmlSecSize ivSize;
|
|
};
|
|
-static int xmlSecNssBlockCipherCtxInit (xmlSecNssBlockCipherCtxPtr ctx,
|
|
- xmlSecBufferPtr in,
|
|
- xmlSecBufferPtr out,
|
|
- int encrypt,
|
|
- const xmlChar* cipherName,
|
|
- xmlSecTransformCtxPtr transformCtx);
|
|
-static int xmlSecNssBlockCipherCtxUpdate (xmlSecNssBlockCipherCtxPtr ctx,
|
|
- xmlSecBufferPtr in,
|
|
- xmlSecBufferPtr out,
|
|
- int encrypt,
|
|
- const xmlChar* cipherName,
|
|
- xmlSecTransformCtxPtr transformCtx);
|
|
-static int xmlSecNssBlockCipherCtxFinal (xmlSecNssBlockCipherCtxPtr ctx,
|
|
- xmlSecBufferPtr in,
|
|
- xmlSecBufferPtr out,
|
|
- int encrypt,
|
|
- const xmlChar* cipherName,
|
|
- xmlSecTransformCtxPtr transformCtx);
|
|
+
|
|
+#define xmlSecNssBlockCipherSize \
|
|
+ ( sizeof( xmlSecTransform ) + sizeof( xmlSecNssBlockCipherCtx ) )
|
|
+
|
|
+#define xmlSecNssBlockCipherGetCtx( transform ) \
|
|
+ ( ( xmlSecNssBlockCipherCtxPtr )( ( ( xmlSecByte* )( transform ) ) + sizeof( xmlSecTransform ) ) )
|
|
+
|
|
+static int
|
|
+xmlSecNssBlockCipherCheckId(
|
|
+ xmlSecTransformPtr transform
|
|
+) {
|
|
+ #ifndef XMLSEC_NO_DES
|
|
+ if( xmlSecTransformCheckId( transform, xmlSecNssTransformDes3CbcId ) ) {
|
|
+ return 1 ;
|
|
+ }
|
|
+ #endif /* XMLSEC_NO_DES */
|
|
+
|
|
+ #ifndef XMLSEC_NO_AES
|
|
+ if( xmlSecTransformCheckId( transform, xmlSecNssTransformAes128CbcId ) ||
|
|
+ xmlSecTransformCheckId( transform, xmlSecNssTransformAes192CbcId ) ||
|
|
+ xmlSecTransformCheckId( transform, xmlSecNssTransformAes256CbcId ) ) {
|
|
+
|
|
+ return 1 ;
|
|
+ }
|
|
+ #endif /* XMLSEC_NO_AES */
|
|
+
|
|
+ return 0 ;
|
|
+}
|
|
+
|
|
+static int
|
|
+xmlSecNssBlockCipherFetchCtx(
|
|
+ xmlSecNssBlockCipherCtxPtr context ,
|
|
+ xmlSecTransformId id
|
|
+) {
|
|
+ xmlSecAssert2( context != NULL, -1 ) ;
|
|
+
|
|
+ #ifndef XMLSEC_NO_DES
|
|
+ if( id == xmlSecNssTransformDes3CbcId ) {
|
|
+ context->cipher = CKM_DES3_CBC ;
|
|
+ context->keyId = xmlSecNssKeyDataDesId ;
|
|
+ } else
|
|
+ #endif /* XMLSEC_NO_DES */
|
|
+
|
|
+ #ifndef XMLSEC_NO_AES
|
|
+ if( id == xmlSecNssTransformAes128CbcId ) {
|
|
+ context->cipher = CKM_AES_CBC ;
|
|
+ context->keyId = xmlSecNssKeyDataAesId ;
|
|
+ } else
|
|
+ if( id == xmlSecNssTransformAes192CbcId ) {
|
|
+ context->cipher = CKM_AES_CBC ;
|
|
+ context->keyId = xmlSecNssKeyDataAesId ;
|
|
+ } else
|
|
+ if( id == xmlSecNssTransformAes256CbcId ) {
|
|
+ context->cipher = CKM_AES_CBC ;
|
|
+ context->keyId = xmlSecNssKeyDataAesId ;
|
|
+ } else
|
|
+ #endif /* XMLSEC_NO_AES */
|
|
+
|
|
+ if( 1 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ NULL ,
|
|
+ NULL ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ return 0 ;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * xmlSecTransformInitializeMethod:
|
|
+ * @transform: the pointer to transform object.
|
|
+ *
|
|
+ * The transform specific initialization method.
|
|
+ *
|
|
+ * Returns 0 on success or a negative value otherwise.
|
|
+ */
|
|
+static int
|
|
+xmlSecNssBlockCipherInitialize(
|
|
+ xmlSecTransformPtr transform
|
|
+) {
|
|
+ xmlSecNssBlockCipherCtxPtr context = NULL ;
|
|
+
|
|
+ xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
|
|
+ xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
|
|
+
|
|
+ context = xmlSecNssBlockCipherGetCtx( transform ) ;
|
|
+ if( context == NULL ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
|
|
+ "xmlSecNssBlockCipherGetCtx" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ if( xmlSecNssBlockCipherFetchCtx( context , transform->id ) < 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
|
|
+ "xmlSecNssBlockCipherFetchCtx" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ context->symkey = NULL ;
|
|
+ context->cipherCtx = NULL ;
|
|
+
|
|
+ return 0 ;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * xmlSecTransformFinalizeMethod:
|
|
+ * @transform: the pointer to transform object.
|
|
+ *
|
|
+ * The transform specific destroy method.
|
|
+ */
|
|
+static void
|
|
+xmlSecNssBlockCipherFinalize(
|
|
+ xmlSecTransformPtr transform
|
|
+) {
|
|
+ xmlSecNssBlockCipherCtxPtr context = NULL ;
|
|
+
|
|
+ xmlSecAssert( xmlSecNssBlockCipherCheckId( transform ) ) ;
|
|
+ xmlSecAssert( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ) ) ;
|
|
+
|
|
+ context = xmlSecNssBlockCipherGetCtx( transform ) ;
|
|
+ if( context == NULL ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
|
|
+ "xmlSecNssBlockCipherGetCtx" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return ;
|
|
+ }
|
|
+
|
|
+ if( context->cipherCtx != NULL ) {
|
|
+ PK11_DestroyContext( context->cipherCtx, PR_TRUE ) ;
|
|
+ context->cipherCtx = NULL ;
|
|
+ }
|
|
+
|
|
+ if( context->symkey != NULL ) {
|
|
+ PK11_FreeSymKey( context->symkey ) ;
|
|
+ context->symkey = NULL ;
|
|
+ }
|
|
+
|
|
+ context->cipher = CKM_INVALID_MECHANISM ;
|
|
+ context->keyId = NULL ;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * xmlSecTransformSetKeyRequirementsMethod:
|
|
+ * @transform: the pointer to transform object.
|
|
+ * @keyReq: the pointer to key requirements structure.
|
|
+ *
|
|
+ * Transform specific method to set transform's key requirements.
|
|
+ *
|
|
+ * Returns 0 on success or a negative value otherwise.
|
|
+ */
|
|
+static int
|
|
+xmlSecNssBlockCipherSetKeyReq(
|
|
+ xmlSecTransformPtr transform ,
|
|
+ xmlSecKeyReqPtr keyReq
|
|
+) {
|
|
+ xmlSecNssBlockCipherCtxPtr context = NULL ;
|
|
+ xmlSecSize cipherSize = 0 ;
|
|
+
|
|
+ xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
|
|
+ xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
|
|
+ xmlSecAssert2( keyReq != NULL , -1 ) ;
|
|
+ xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
|
|
+
|
|
+ context = xmlSecNssBlockCipherGetCtx( transform ) ;
|
|
+ if( context == NULL ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
|
|
+ "xmlSecNssBlockCipherGetCtx" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ keyReq->keyId = context->keyId ;
|
|
+ keyReq->keyType = xmlSecKeyDataTypeSymmetric ;
|
|
+
|
|
+ if( transform->operation == xmlSecTransformOperationEncrypt ) {
|
|
+ keyReq->keyUsage = xmlSecKeyUsageEncrypt ;
|
|
+ } else {
|
|
+ keyReq->keyUsage = xmlSecKeyUsageDecrypt ;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ if( context->symkey != NULL )
|
|
+ cipherSize = PK11_GetKeyLength( context->symkey ) ;
|
|
+
|
|
+ keyReq->keyBitsSize = cipherSize * 8 ;
|
|
+ */
|
|
+
|
|
+ return 0 ;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * xmlSecTransformSetKeyMethod:
|
|
+ * @transform: the pointer to transform object.
|
|
+ * @key: the pointer to key.
|
|
+ *
|
|
+ * The transform specific method to set the key for use.
|
|
+ *
|
|
+ * Returns 0 on success or a negative value otherwise.
|
|
+ */
|
|
+static int
|
|
+xmlSecNssBlockCipherSetKey(
|
|
+ xmlSecTransformPtr transform ,
|
|
+ xmlSecKeyPtr key
|
|
+) {
|
|
+ xmlSecNssBlockCipherCtxPtr context = NULL ;
|
|
+ xmlSecKeyDataPtr keyData = NULL ;
|
|
+ PK11SymKey* symkey = NULL ;
|
|
+ CK_ATTRIBUTE_TYPE operation ;
|
|
+ int ivLen ;
|
|
+
|
|
+ xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
|
|
+ xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
|
|
+ xmlSecAssert2( key != NULL , -1 ) ;
|
|
+ xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
|
|
+
|
|
+ context = xmlSecNssBlockCipherGetCtx( transform ) ;
|
|
+ if( context == NULL || context->keyId == NULL || context->symkey != NULL ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
|
|
+ "xmlSecNssBlockCipherGetCtx" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+ xmlSecAssert2( xmlSecKeyCheckId( key, context->keyId ), -1 ) ;
|
|
+
|
|
+ keyData = xmlSecKeyGetValue( key ) ;
|
|
+ if( keyData == NULL ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecKeyGetName( key ) ) ,
|
|
+ "xmlSecKeyGetValue" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ if( ( symkey = xmlSecNssSymKeyDataGetKey( keyData ) ) == NULL ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecKeyDataGetName( keyData ) ) ,
|
|
+ "xmlSecNssSymKeyDataGetKey" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ context->symkey = symkey ;
|
|
+
|
|
+ return 0 ;
|
|
+}
|
|
+
|
|
static int
|
|
xmlSecNssBlockCipherCtxInit(xmlSecNssBlockCipherCtxPtr ctx,
|
|
xmlSecBufferPtr in, xmlSecBufferPtr out,
|
|
int encrypt,
|
|
const xmlChar* cipherName,
|
|
xmlSecTransformCtxPtr transformCtx) {
|
|
- SECItem keyItem;
|
|
SECItem ivItem;
|
|
- PK11SlotInfo* slot;
|
|
- PK11SymKey* symKey;
|
|
+ SECItem* secParam = NULL ;
|
|
+ xmlSecBufferPtr ivBuf = NULL ;
|
|
int ivLen;
|
|
- SECStatus rv;
|
|
- int ret;
|
|
|
|
xmlSecAssert2(ctx != NULL, -1);
|
|
- xmlSecAssert2(ctx->cipher != 0, -1);
|
|
+ xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
|
|
+ xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
|
|
xmlSecAssert2(ctx->cipherCtx == NULL, -1);
|
|
- xmlSecAssert2(ctx->keyInitialized != 0, -1);
|
|
- xmlSecAssert2(ctx->ctxInitialized == 0, -1);
|
|
+ xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
|
|
xmlSecAssert2(in != NULL, -1);
|
|
xmlSecAssert2(out != NULL, -1);
|
|
xmlSecAssert2(transformCtx != NULL, -1);
|
|
|
|
ivLen = PK11_GetIVLength(ctx->cipher);
|
|
- xmlSecAssert2(ivLen > 0, -1);
|
|
- xmlSecAssert2((xmlSecSize)ivLen <= sizeof(ctx->iv), -1);
|
|
+ if( ivLen < 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ NULL ,
|
|
+ "PK11_GetIVLength" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ if( ( ivBuf = xmlSecBufferCreate( ivLen ) ) == NULL ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ NULL ,
|
|
+ "xmlSecBufferCreate" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
|
|
if(encrypt) {
|
|
- /* generate random iv */
|
|
- rv = PK11_GenerateRandom(ctx->iv, ivLen);
|
|
- if(rv != SECSuccess) {
|
|
+ if( PK11_GenerateRandom( ivBuf->data , ivLen ) != SECSuccess ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"PK11_GenerateRandom",
|
|
XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
- "size=%d", ivLen);
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
return(-1);
|
|
}
|
|
+ if( xmlSecBufferSetSize( ivBuf , ivLen ) < 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ NULL ,
|
|
+ "xmlSecBufferSetSize" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
|
|
- /* write iv to the output */
|
|
- ret = xmlSecBufferAppend(out, ctx->iv, ivLen);
|
|
- if(ret < 0) {
|
|
+ if( xmlSecBufferAppend( out , ivBuf->data , ivLen ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"xmlSecBufferAppend",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", ivLen);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
return(-1);
|
|
}
|
|
|
|
} else {
|
|
- /* if we don't have enough data, exit and hope that
|
|
- * we'll have iv next time */
|
|
- if(xmlSecBufferGetSize(in) < (xmlSecSize)ivLen) {
|
|
- return(0);
|
|
- }
|
|
-
|
|
- /* copy iv to our buffer*/
|
|
- xmlSecAssert2(xmlSecBufferGetData(in) != NULL, -1);
|
|
- memcpy(ctx->iv, xmlSecBufferGetData(in), ivLen);
|
|
-
|
|
- /* and remove from input */
|
|
- ret = xmlSecBufferRemoveHead(in, ivLen);
|
|
- if(ret < 0) {
|
|
+ if( xmlSecBufferSetData( ivBuf , in->data , ivLen ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
- "xmlSecBufferRemoveHead",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", ivLen);
|
|
+ "xmlSecBufferSetData",
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
return(-1);
|
|
}
|
|
}
|
|
|
|
- memset(&keyItem, 0, sizeof(keyItem));
|
|
- keyItem.data = ctx->key;
|
|
- keyItem.len = ctx->keySize;
|
|
- memset(&ivItem, 0, sizeof(ivItem));
|
|
- ivItem.data = ctx->iv;
|
|
- ivItem.len = ctx->ivSize;
|
|
-
|
|
- slot = PK11_GetBestSlot(ctx->cipher, NULL);
|
|
- if(slot == NULL) {
|
|
+ if( xmlSecBufferRemoveHead( in , ivLen ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
- "PK11_GetBestSlot",
|
|
+ "xmlSecBufferRemoveHead",
|
|
XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
return(-1);
|
|
}
|
|
|
|
- symKey = PK11_ImportSymKey(slot, ctx->cipher, PK11_OriginDerive,
|
|
- CKA_SIGN, &keyItem, NULL);
|
|
- if(symKey == NULL) {
|
|
+ ivItem.data = xmlSecBufferGetData( ivBuf ) ;
|
|
+ ivItem.len = xmlSecBufferGetSize( ivBuf ) ;
|
|
+ if( ( secParam = PK11_ParamFromIV( ctx->cipher , &ivItem ) ) == NULL ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
- "PK11_ImportSymKey",
|
|
+ "PK11_ParamFromIV",
|
|
XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
- PK11_FreeSlot(slot);
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
return(-1);
|
|
}
|
|
|
|
ctx->cipherCtx = PK11_CreateContextBySymKey(ctx->cipher,
|
|
(encrypt) ? CKA_ENCRYPT : CKA_DECRYPT,
|
|
- symKey, &ivItem);
|
|
+ ctx->symkey, secParam);
|
|
if(ctx->cipherCtx == NULL) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
- "PK11_CreateContextBySymKey",
|
|
+ "xmlSecBufferRemoveHead",
|
|
XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
- PK11_FreeSymKey(symKey);
|
|
- PK11_FreeSlot(slot);
|
|
+ SECITEM_FreeItem( secParam , PR_TRUE ) ;
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
return(-1);
|
|
}
|
|
|
|
- ctx->ctxInitialized = 1;
|
|
- PK11_FreeSymKey(symKey);
|
|
- PK11_FreeSlot(slot);
|
|
+ SECITEM_FreeItem( secParam , PR_TRUE ) ;
|
|
+ xmlSecBufferDestroy( ivBuf ) ;
|
|
return(0);
|
|
}
|
|
|
|
+/**
|
|
+ * Block cipher transform update
|
|
+ */
|
|
static int
|
|
xmlSecNssBlockCipherCtxUpdate(xmlSecNssBlockCipherCtxPtr ctx,
|
|
xmlSecBufferPtr in, xmlSecBufferPtr out,
|
|
@@ -192,54 +433,49 @@
|
|
const xmlChar* cipherName,
|
|
xmlSecTransformCtxPtr transformCtx) {
|
|
xmlSecSize inSize, inBlocks, outSize;
|
|
- int blockLen;
|
|
+ int blockSize;
|
|
int outLen = 0;
|
|
xmlSecByte* outBuf;
|
|
- SECStatus rv;
|
|
- int ret;
|
|
|
|
xmlSecAssert2(ctx != NULL, -1);
|
|
- xmlSecAssert2(ctx->cipher != 0, -1);
|
|
+ xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
|
|
+ xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
|
|
xmlSecAssert2(ctx->cipherCtx != NULL, -1);
|
|
- xmlSecAssert2(ctx->ctxInitialized != 0, -1);
|
|
+ xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
|
|
xmlSecAssert2(in != NULL, -1);
|
|
xmlSecAssert2(out != NULL, -1);
|
|
xmlSecAssert2(transformCtx != NULL, -1);
|
|
|
|
- blockLen = PK11_GetBlockSize(ctx->cipher, NULL);
|
|
- xmlSecAssert2(blockLen > 0, -1);
|
|
+ if( ( blockSize = PK11_GetBlockSize( ctx->cipher , NULL ) ) < 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( cipherName ) ,
|
|
+ "PK11_GetBlockSize" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
|
|
inSize = xmlSecBufferGetSize(in);
|
|
outSize = xmlSecBufferGetSize(out);
|
|
-
|
|
- if(inSize < (xmlSecSize)blockLen) {
|
|
- return(0);
|
|
+
|
|
+ inBlocks = ( encrypt != 0 ? inSize : ( inSize - 1 ) ) / blockSize ;
|
|
+ inSize = inBlocks * blockSize ;
|
|
+
|
|
+ if( inSize < blockSize ) {
|
|
+ return 0 ;
|
|
}
|
|
|
|
- if(encrypt) {
|
|
- inBlocks = inSize / ((xmlSecSize)blockLen);
|
|
- } else {
|
|
- /* we want to have the last block in the input buffer
|
|
- * for padding check */
|
|
- inBlocks = (inSize - 1) / ((xmlSecSize)blockLen);
|
|
- }
|
|
- inSize = inBlocks * ((xmlSecSize)blockLen);
|
|
-
|
|
- /* we write out the input size plus may be one block */
|
|
- ret = xmlSecBufferSetMaxSize(out, outSize + inSize + blockLen);
|
|
- if(ret < 0) {
|
|
+ if( xmlSecBufferSetMaxSize( out , outSize + inSize + blockSize ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"xmlSecBufferSetMaxSize",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", outSize + inSize + blockLen);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
outBuf = xmlSecBufferGetData(out) + outSize;
|
|
|
|
- rv = PK11_CipherOp(ctx->cipherCtx, outBuf, &outLen, inSize + blockLen,
|
|
- xmlSecBufferGetData(in), inSize);
|
|
- if(rv != SECSuccess) {
|
|
+ if(PK11_CipherOp( ctx->cipherCtx , outBuf , &outLen , inSize + blockSize , xmlSecBufferGetData( in ) , inSize ) != SECSuccess ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"PK11_CipherOp",
|
|
@@ -247,27 +483,22 @@
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
- xmlSecAssert2((xmlSecSize)outLen == inSize, -1);
|
|
|
|
- /* set correct output buffer size */
|
|
- ret = xmlSecBufferSetSize(out, outSize + outLen);
|
|
- if(ret < 0) {
|
|
+ if( xmlSecBufferSetSize( out , outSize + outLen ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"xmlSecBufferSetSize",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", outSize + outLen);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
|
|
- /* remove the processed block from input */
|
|
- ret = xmlSecBufferRemoveHead(in, inSize);
|
|
- if(ret < 0) {
|
|
+ if( xmlSecBufferRemoveHead( in , inSize ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"xmlSecBufferRemoveHead",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", inSize);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
return(0);
|
|
@@ -281,81 +512,82 @@
|
|
const xmlChar* cipherName,
|
|
xmlSecTransformCtxPtr transformCtx) {
|
|
xmlSecSize inSize, outSize;
|
|
- int blockLen, outLen = 0;
|
|
+ int blockSize, outLen = 0;
|
|
xmlSecByte* inBuf;
|
|
xmlSecByte* outBuf;
|
|
- SECStatus rv;
|
|
- int ret;
|
|
|
|
xmlSecAssert2(ctx != NULL, -1);
|
|
- xmlSecAssert2(ctx->cipher != 0, -1);
|
|
+ xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
|
|
+ xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
|
|
xmlSecAssert2(ctx->cipherCtx != NULL, -1);
|
|
- xmlSecAssert2(ctx->ctxInitialized != 0, -1);
|
|
+ xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
|
|
xmlSecAssert2(in != NULL, -1);
|
|
xmlSecAssert2(out != NULL, -1);
|
|
xmlSecAssert2(transformCtx != NULL, -1);
|
|
|
|
- blockLen = PK11_GetBlockSize(ctx->cipher, NULL);
|
|
- xmlSecAssert2(blockLen > 0, -1);
|
|
+ if( ( blockSize = PK11_GetBlockSize( ctx->cipher , NULL ) ) < 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( cipherName ) ,
|
|
+ "PK11_GetBlockSize" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
|
|
inSize = xmlSecBufferGetSize(in);
|
|
outSize = xmlSecBufferGetSize(out);
|
|
|
|
+ /******************************************************************/
|
|
if(encrypt != 0) {
|
|
- xmlSecAssert2(inSize < (xmlSecSize)blockLen, -1);
|
|
+ xmlSecAssert2( inSize < blockSize, -1 ) ;
|
|
|
|
/* create padding */
|
|
- ret = xmlSecBufferSetMaxSize(in, blockLen);
|
|
- if(ret < 0) {
|
|
+ if( xmlSecBufferSetMaxSize( in , blockSize ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"xmlSecBufferSetMaxSize",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", blockLen);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
inBuf = xmlSecBufferGetData(in);
|
|
|
|
- /* generate random padding */
|
|
- if((xmlSecSize)blockLen > (inSize + 1)) {
|
|
- rv = PK11_GenerateRandom(inBuf + inSize, blockLen - inSize - 1);
|
|
- if(rv != SECSuccess) {
|
|
+ /* generate random */
|
|
+ if( blockSize > ( inSize + 1 ) ) {
|
|
+ if( PK11_GenerateRandom( inBuf + inSize, blockSize - inSize - 1 ) != SECSuccess ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"PK11_GenerateRandom",
|
|
XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
- "size=%d", blockLen - inSize - 1);
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
}
|
|
- inBuf[blockLen - 1] = blockLen - inSize;
|
|
- inSize = blockLen;
|
|
+ inBuf[blockSize-1] = blockSize - inSize ;
|
|
+ inSize = blockSize ;
|
|
} else {
|
|
- if(inSize != (xmlSecSize)blockLen) {
|
|
+ if( inSize != blockSize ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
NULL,
|
|
- XMLSEC_ERRORS_R_INVALID_DATA,
|
|
- "data=%d;block=%d", inSize, blockLen);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
}
|
|
|
|
- /* process last block */
|
|
- ret = xmlSecBufferSetMaxSize(out, outSize + 2 * blockLen);
|
|
- if(ret < 0) {
|
|
+ /* process the last block */
|
|
+ if( xmlSecBufferSetMaxSize( out , outSize + inSize + blockSize ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"xmlSecBufferSetMaxSize",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", outSize + 2 * blockLen);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
outBuf = xmlSecBufferGetData(out) + outSize;
|
|
|
|
- rv = PK11_CipherOp(ctx->cipherCtx, outBuf, &outLen, 2 * blockLen,
|
|
- xmlSecBufferGetData(in), inSize);
|
|
- if(rv != SECSuccess) {
|
|
+ if( PK11_CipherOp( ctx->cipherCtx , outBuf , &outLen , inSize + blockSize , xmlSecBufferGetData( in ) , inSize ) != SECSuccess ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
"PK11_CipherOp",
|
|
@@ -363,300 +595,169 @@
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
- xmlSecAssert2((xmlSecSize)outLen == inSize, -1);
|
|
|
|
if(encrypt == 0) {
|
|
/* check padding */
|
|
- if(outLen < outBuf[blockLen - 1]) {
|
|
+ if( outLen < outBuf[blockSize-1] ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
NULL,
|
|
- XMLSEC_ERRORS_R_INVALID_DATA,
|
|
- "padding=%d;buffer=%d",
|
|
- outBuf[blockLen - 1], outLen);
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
- outLen -= outBuf[blockLen - 1];
|
|
+ outLen -= outBuf[blockSize-1] ;
|
|
}
|
|
|
|
- /* set correct output buffer size */
|
|
- ret = xmlSecBufferSetSize(out, outSize + outLen);
|
|
- if(ret < 0) {
|
|
- xmlSecError(XMLSEC_ERRORS_HERE,
|
|
- xmlSecErrorsSafeString(cipherName),
|
|
- "xmlSecBufferSetSize",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", outSize + outLen);
|
|
- return(-1);
|
|
- }
|
|
+ /******************************************************************/
|
|
|
|
- /* remove the processed block from input */
|
|
- ret = xmlSecBufferRemoveHead(in, inSize);
|
|
- if(ret < 0) {
|
|
+ /******************************************************************
|
|
+ if( xmlSecBufferSetMaxSize( out , outSize + blockSize ) < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(cipherName),
|
|
- "xmlSecBufferRemoveHead",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
- "size=%d", inSize);
|
|
- return(-1);
|
|
- }
|
|
-
|
|
- return(0);
|
|
-}
|
|
-
|
|
-
|
|
-/******************************************************************************
|
|
- *
|
|
- * EVP Block Cipher transforms
|
|
- *
|
|
- * xmlSecNssBlockCipherCtx block is located after xmlSecTransform structure
|
|
- *
|
|
- *****************************************************************************/
|
|
-#define xmlSecNssBlockCipherSize \
|
|
- (sizeof(xmlSecTransform) + sizeof(xmlSecNssBlockCipherCtx))
|
|
-#define xmlSecNssBlockCipherGetCtx(transform) \
|
|
- ((xmlSecNssBlockCipherCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
|
|
-
|
|
-static int xmlSecNssBlockCipherInitialize (xmlSecTransformPtr transform);
|
|
-static void xmlSecNssBlockCipherFinalize (xmlSecTransformPtr transform);
|
|
-static int xmlSecNssBlockCipherSetKeyReq (xmlSecTransformPtr transform,
|
|
- xmlSecKeyReqPtr keyReq);
|
|
-static int xmlSecNssBlockCipherSetKey (xmlSecTransformPtr transform,
|
|
- xmlSecKeyPtr key);
|
|
-static int xmlSecNssBlockCipherExecute (xmlSecTransformPtr transform,
|
|
- int last,
|
|
- xmlSecTransformCtxPtr transformCtx);
|
|
-static int xmlSecNssBlockCipherCheckId (xmlSecTransformPtr transform);
|
|
-
|
|
-
|
|
-
|
|
-static int
|
|
-xmlSecNssBlockCipherCheckId(xmlSecTransformPtr transform) {
|
|
-#ifndef XMLSEC_NO_DES
|
|
- if(xmlSecTransformCheckId(transform, xmlSecNssTransformDes3CbcId)) {
|
|
- return(1);
|
|
- }
|
|
-#endif /* XMLSEC_NO_DES */
|
|
-
|
|
-#ifndef XMLSEC_NO_AES
|
|
- if(xmlSecTransformCheckId(transform, xmlSecNssTransformAes128CbcId) ||
|
|
- xmlSecTransformCheckId(transform, xmlSecNssTransformAes192CbcId) ||
|
|
- xmlSecTransformCheckId(transform, xmlSecNssTransformAes256CbcId)) {
|
|
-
|
|
- return(1);
|
|
- }
|
|
-#endif /* XMLSEC_NO_AES */
|
|
-
|
|
- return(0);
|
|
-}
|
|
-
|
|
-static int
|
|
-xmlSecNssBlockCipherInitialize(xmlSecTransformPtr transform) {
|
|
- xmlSecNssBlockCipherCtxPtr ctx;
|
|
-
|
|
- xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
|
|
- xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
|
|
-
|
|
- ctx = xmlSecNssBlockCipherGetCtx(transform);
|
|
- xmlSecAssert2(ctx != NULL, -1);
|
|
-
|
|
- memset(ctx, 0, sizeof(xmlSecNssBlockCipherCtx));
|
|
-
|
|
-#ifndef XMLSEC_NO_DES
|
|
- if(transform->id == xmlSecNssTransformDes3CbcId) {
|
|
- ctx->cipher = CKM_DES3_CBC;
|
|
- ctx->keyId = xmlSecNssKeyDataDesId;
|
|
- ctx->keySize = 24;
|
|
- } else
|
|
-#endif /* XMLSEC_NO_DES */
|
|
-
|
|
-#ifndef XMLSEC_NO_AES
|
|
- if(transform->id == xmlSecNssTransformAes128CbcId) {
|
|
- ctx->cipher = CKM_AES_CBC;
|
|
- ctx->keyId = xmlSecNssKeyDataAesId;
|
|
- ctx->keySize = 16;
|
|
- } else if(transform->id == xmlSecNssTransformAes192CbcId) {
|
|
- ctx->cipher = CKM_AES_CBC;
|
|
- ctx->keyId = xmlSecNssKeyDataAesId;
|
|
- ctx->keySize = 24;
|
|
- } else if(transform->id == xmlSecNssTransformAes256CbcId) {
|
|
- ctx->cipher = CKM_AES_CBC;
|
|
- ctx->keyId = xmlSecNssKeyDataAesId;
|
|
- ctx->keySize = 32;
|
|
- } else
|
|
-#endif /* XMLSEC_NO_AES */
|
|
-
|
|
- if(1) {
|
|
- xmlSecError(XMLSEC_ERRORS_HERE,
|
|
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
|
|
- NULL,
|
|
- XMLSEC_ERRORS_R_INVALID_TRANSFORM,
|
|
+ "xmlSecBufferSetMaxSize",
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
- }
|
|
-
|
|
- return(0);
|
|
-}
|
|
-
|
|
-static void
|
|
-xmlSecNssBlockCipherFinalize(xmlSecTransformPtr transform) {
|
|
- xmlSecNssBlockCipherCtxPtr ctx;
|
|
-
|
|
- xmlSecAssert(xmlSecNssBlockCipherCheckId(transform));
|
|
- xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize));
|
|
-
|
|
- ctx = xmlSecNssBlockCipherGetCtx(transform);
|
|
- xmlSecAssert(ctx != NULL);
|
|
-
|
|
- if(ctx->cipherCtx != NULL) {
|
|
- PK11_DestroyContext(ctx->cipherCtx, PR_TRUE);
|
|
}
|
|
-
|
|
- memset(ctx, 0, sizeof(xmlSecNssBlockCipherCtx));
|
|
-}
|
|
|
|
-static int
|
|
-xmlSecNssBlockCipherSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
|
|
- xmlSecNssBlockCipherCtxPtr ctx;
|
|
-
|
|
- xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
|
|
- xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
|
|
- xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
|
|
- xmlSecAssert2(keyReq != NULL, -1);
|
|
-
|
|
- ctx = xmlSecNssBlockCipherGetCtx(transform);
|
|
- xmlSecAssert2(ctx != NULL, -1);
|
|
- xmlSecAssert2(ctx->keyId != NULL, -1);
|
|
+ outBuf = xmlSecBufferGetData( out ) + outSize ;
|
|
+ if( PK11_DigestFinal( ctx->cipherCtx , outBuf , &outLen , blockSize ) != SECSuccess ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( cipherName ) ,
|
|
+ "PK11_DigestFinal" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+ ******************************************************************/
|
|
+
|
|
+ if( xmlSecBufferSetSize( out , outSize + outLen ) < 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( cipherName ) ,
|
|
+ "xmlSecBufferSetSize" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+ if( xmlSecBufferRemoveHead( in , inSize ) < 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( cipherName ) ,
|
|
+ "xmlSecBufferRemoveHead" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
+
|
|
+/* PK11_Finalize( ctx->cipherCtx ) ;*/
|
|
+ PK11_DestroyContext(ctx->cipherCtx, PR_TRUE);
|
|
+ ctx->cipherCtx = NULL ;
|
|
|
|
- keyReq->keyId = ctx->keyId;
|
|
- keyReq->keyType = xmlSecKeyDataTypeSymmetric;
|
|
- if(transform->operation == xmlSecTransformOperationEncrypt) {
|
|
- keyReq->keyUsage = xmlSecKeyUsageEncrypt;
|
|
- } else {
|
|
- keyReq->keyUsage = xmlSecKeyUsageDecrypt;
|
|
- }
|
|
- keyReq->keyBitsSize = 8 * ctx->keySize;
|
|
return(0);
|
|
}
|
|
|
|
-static int
|
|
-xmlSecNssBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
|
|
- xmlSecNssBlockCipherCtxPtr ctx;
|
|
- xmlSecBufferPtr buffer;
|
|
+/**
|
|
+ * xmlSecTransformExecuteMethod:
|
|
+ * @transform: the pointer to transform object.
|
|
+ * @last: the flag: if set to 1 then it's the last data chunk.
|
|
+ * @transformCtx: the pointer to transform context object.
|
|
+ *
|
|
+ * Transform specific method to process a chunk of data.
|
|
+ *
|
|
+ * Returns 0 on success or a negative value otherwise.
|
|
+ */
|
|
+xmlSecNssBlockCipherExecute(
|
|
+ xmlSecTransformPtr transform ,
|
|
+ int last ,
|
|
+ xmlSecTransformCtxPtr transformCtx
|
|
+) {
|
|
+ xmlSecNssBlockCipherCtxPtr context = NULL ;
|
|
+ xmlSecBufferPtr inBuf = NULL ;
|
|
+ xmlSecBufferPtr outBuf = NULL ;
|
|
+ const xmlChar* cipherName ;
|
|
+ int operation ;
|
|
+ int rtv ;
|
|
|
|
xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
|
|
- xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
|
|
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
|
|
- xmlSecAssert2(key != NULL, -1);
|
|
-
|
|
- ctx = xmlSecNssBlockCipherGetCtx(transform);
|
|
- xmlSecAssert2(ctx != NULL, -1);
|
|
- xmlSecAssert2(ctx->cipher != 0, -1);
|
|
- xmlSecAssert2(ctx->keyInitialized == 0, -1);
|
|
- xmlSecAssert2(ctx->keyId != NULL, -1);
|
|
- xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1);
|
|
-
|
|
- xmlSecAssert2(ctx->keySize > 0, -1);
|
|
- xmlSecAssert2(ctx->keySize <= sizeof(ctx->key), -1);
|
|
|
|
- buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key));
|
|
- xmlSecAssert2(buffer != NULL, -1);
|
|
+ xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
|
|
+ xmlSecAssert2( transformCtx != NULL , -1 ) ;
|
|
|
|
- if(xmlSecBufferGetSize(buffer) < ctx->keySize) {
|
|
+ context = xmlSecNssBlockCipherGetCtx( transform ) ;
|
|
+ if( context == NULL ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
|
|
- NULL,
|
|
- XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
|
|
- "keySize=%d;expected=%d",
|
|
- xmlSecBufferGetSize(buffer), ctx->keySize);
|
|
- return(-1);
|
|
+ "xmlSecNssBlockCipherGetCtx" ,
|
|
+ XMLSEC_ERRORS_R_CRYPTO_FAILED ,
|
|
+ XMLSEC_ERRORS_NO_MESSAGE ) ;
|
|
}
|
|
-
|
|
- xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1);
|
|
- memcpy(ctx->key, xmlSecBufferGetData(buffer), ctx->keySize);
|
|
-
|
|
- ctx->keyInitialized = 1;
|
|
- return(0);
|
|
-}
|
|
-
|
|
-static int
|
|
-xmlSecNssBlockCipherExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
|
|
- xmlSecNssBlockCipherCtxPtr ctx;
|
|
- xmlSecBufferPtr in, out;
|
|
- int ret;
|
|
-
|
|
- xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
|
|
- xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
|
|
- xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
|
|
- xmlSecAssert2(transformCtx != NULL, -1);
|
|
|
|
- in = &(transform->inBuf);
|
|
- out = &(transform->outBuf);
|
|
-
|
|
- ctx = xmlSecNssBlockCipherGetCtx(transform);
|
|
- xmlSecAssert2(ctx != NULL, -1);
|
|
+ inBuf = &( transform->inBuf ) ;
|
|
+ outBuf = &( transform->outBuf ) ;
|
|
|
|
if(transform->status == xmlSecTransformStatusNone) {
|
|
transform->status = xmlSecTransformStatusWorking;
|
|
}
|
|
|
|
+ operation = ( transform->operation == xmlSecTransformOperationEncrypt ) ? 1 : 0 ;
|
|
+ cipherName = xmlSecTransformGetName( transform ) ;
|
|
+
|
|
if(transform->status == xmlSecTransformStatusWorking) {
|
|
- if(ctx->ctxInitialized == 0) {
|
|
- ret = xmlSecNssBlockCipherCtxInit(ctx, in, out,
|
|
- (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
|
|
- xmlSecTransformGetName(transform), transformCtx);
|
|
- if(ret < 0) {
|
|
+ if( context->cipherCtx == NULL ) {
|
|
+ rtv = xmlSecNssBlockCipherCtxInit( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
|
|
+ if( rtv < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
|
|
"xmlSecNssBlockCipherCtxInit",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
+ XMLSEC_ERRORS_R_INVALID_STATUS,
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
}
|
|
- if((ctx->ctxInitialized == 0) && (last != 0)) {
|
|
+ if( context->cipherCtx == NULL && last != 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
|
|
NULL,
|
|
- XMLSEC_ERRORS_R_INVALID_DATA,
|
|
+ XMLSEC_ERRORS_R_INVALID_STATUS,
|
|
"not enough data to initialize transform");
|
|
return(-1);
|
|
}
|
|
|
|
- if(ctx->ctxInitialized != 0) {
|
|
- ret = xmlSecNssBlockCipherCtxUpdate(ctx, in, out,
|
|
- (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
|
|
- xmlSecTransformGetName(transform), transformCtx);
|
|
- if(ret < 0) {
|
|
+ if( context->cipherCtx != NULL ) {
|
|
+ rtv = xmlSecNssBlockCipherCtxUpdate( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
|
|
+ if( rtv < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
|
|
"xmlSecNssBlockCipherCtxUpdate",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
+ XMLSEC_ERRORS_R_INVALID_STATUS,
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
}
|
|
|
|
if(last) {
|
|
- ret = xmlSecNssBlockCipherCtxFinal(ctx, in, out,
|
|
- (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
|
|
- xmlSecTransformGetName(transform), transformCtx);
|
|
- if(ret < 0) {
|
|
+ rtv = xmlSecNssBlockCipherCtxFinal( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
|
|
+ if( rtv < 0 ) {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
|
|
"xmlSecNssBlockCipherCtxFinal",
|
|
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
|
|
+ XMLSEC_ERRORS_R_INVALID_STATUS,
|
|
XMLSEC_ERRORS_NO_MESSAGE);
|
|
return(-1);
|
|
}
|
|
transform->status = xmlSecTransformStatusFinished;
|
|
}
|
|
} else if(transform->status == xmlSecTransformStatusFinished) {
|
|
- /* the only way we can get here is if there is no input */
|
|
- xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1);
|
|
- } else if(transform->status == xmlSecTransformStatusNone) {
|
|
- /* the only way we can get here is if there is no enough data in the input */
|
|
- xmlSecAssert2(last == 0, -1);
|
|
+ if( xmlSecBufferGetSize( inBuf ) != 0 ) {
|
|
+ xmlSecError( XMLSEC_ERRORS_HERE ,
|
|
+ xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
|
|
+ NULL ,
|
|
+ XMLSEC_ERRORS_R_INVALID_STATUS ,
|
|
+ "status=%d", transform->status ) ;
|
|
+ return -1 ;
|
|
+ }
|
|
} else {
|
|
xmlSecError(XMLSEC_ERRORS_HERE,
|
|
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
|