xmlsecurityengine/xmlseccrypto/src/xmlsecc_digests.cpp
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /** 
       
     2  * XMLSec library
       
     3  *
       
     4  * This is free software; see Copyright file in the source
       
     5  * distribution for preciese wording.
       
     6  * 
       
     7  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
       
     8  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
     9  */
       
    10 #include "xmlsecc_globals.h"
       
    11 
       
    12 #include <string.h>
       
    13 #include <e32err.h>
       
    14 #include "xmlsecc_config.h"
       
    15 #include "xmlsec_xmlsec.h"
       
    16 #include "xmlsec_keys.h"
       
    17 #include "xmlsec_transforms.h"
       
    18 #include "xmlsec_errors.h"
       
    19 #include "xmlsec_error_flag.h"
       
    20 
       
    21 #include "xmlsecc_app.h"
       
    22 #include "xmlsecc_crypto.h"
       
    23 #include "xmlsecc_cryptowrapper.h"		// replace gnutils/gnutls.h
       
    24 
       
    25 //#define XMLSEC_SYMBIAN_MAX_DIGEST_SIZE		32
       
    26 
       
    27 /**************************************************************************
       
    28  *
       
    29  * Internal SymbianCrypto Digest CTX
       
    30  *
       
    31  *****************************************************************************/
       
    32 typedef struct _xmlSecSymbianCryptoDigestCtx 
       
    33                                xmlSecSymbianCryptoDigestCtx, *xmlSecSymbianCryptoDigestCtxPtr;
       
    34 struct _xmlSecSymbianCryptoDigestCtx {
       
    35     int			digest;
       
    36     ScMDHd		digestCtx;
       
    37     xmlSecByte	 	dgst[XMLSEC_SYMBIAN_MAX_DIGEST_SIZE];
       
    38     xmlSecSize		dgstSize;	/* dgst size in bytes */
       
    39 };	    
       
    40 
       
    41 xmlSecTransformGetDataTypeMethod const xmlSecCrpytoGetDataTypeMethod  = xmlSecTransformDefaultGetDataType;
       
    42 xmlSecTransformPushBinMethod const xmlSecCryptoPushBinMethod = xmlSecTransformDefaultPushBin;
       
    43 xmlSecTransformPopBinMethod const xmlSecCryptoPopBinMethod = xmlSecTransformDefaultPopBin;
       
    44 
       
    45 /******************************************************************************
       
    46  *
       
    47  * Digest transforms
       
    48  *
       
    49  * xmlSecSymbianCryptoDigestCtx is located after xmlSecTransform
       
    50  *
       
    51  *****************************************************************************/
       
    52 #define xmlSecSymbianCryptoDigestSize	\
       
    53     (sizeof(xmlSecTransform) + sizeof(xmlSecSymbianCryptoDigestCtx))	
       
    54 #define xmlSecSymbianCryptoDigestGetCtx(transform) \
       
    55     ((xmlSecSymbianCryptoDigestCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
       
    56 
       
    57 static int 	xmlSecSymbianCryptoDigestInitialize		(xmlSecTransformPtr transform);
       
    58 static void 	xmlSecSymbianCryptoDigestFinalize		(xmlSecTransformPtr transform);
       
    59 static int	xmlSecSymbianCryptoDigestVerify		(xmlSecTransformPtr transform, 
       
    60 							 const xmlSecByte* data, 
       
    61 							 xmlSecSize dataSize,
       
    62 							 xmlSecTransformCtxPtr transformCtx);
       
    63 static int 	xmlSecSymbianCryptoDigestExecute		(xmlSecTransformPtr transform, 
       
    64 							 int last, 
       
    65 							 xmlSecTransformCtxPtr transformCtx);
       
    66 static int	xmlSecSymbianCryptoDigestCheckId		(xmlSecTransformPtr transform);
       
    67 
       
    68 static int
       
    69 xmlSecSymbianCryptoDigestCheckId(xmlSecTransformPtr transform) {
       
    70 
       
    71 #ifndef XMLSEC_NO_SHA1
       
    72     if(xmlSecTransformCheckId(transform, xmlSecSymbianCryptoTransformSha1Id)) {
       
    73 	return(1);
       
    74     }
       
    75 #endif /* XMLSEC_NO_SHA1 */    
       
    76 
       
    77     return(0);
       
    78 }
       
    79 
       
    80 static int 
       
    81 xmlSecSymbianCryptoDigestInitialize(xmlSecTransformPtr transform) {
       
    82     xmlSecSymbianCryptoDigestCtxPtr ctx;
       
    83 #ifndef XMLSEC_GNUTLS_OLD
       
    84     TInt ret;
       
    85 #endif /* XMLSEC_GNUTLS_OLD */
       
    86 
       
    87     xmlSecAssert2(xmlSecSymbianCryptoDigestCheckId(transform), -1);
       
    88     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecSymbianCryptoDigestSize), -1);
       
    89 
       
    90     ctx = xmlSecSymbianCryptoDigestGetCtx(transform);
       
    91     xmlSecAssert2(ctx, -1);
       
    92 
       
    93     /* initialize context */
       
    94     memset(ctx, 0, sizeof(xmlSecSymbianCryptoDigestCtx));
       
    95 
       
    96 #ifndef XMLSEC_NO_SHA1
       
    97     if(xmlSecTransformCheckId(transform, xmlSecSymbianCryptoTransformSha1Id)) {
       
    98 	ctx->digest = SC_MD_SHA1;
       
    99     } else
       
   100 #endif /* XMLSEC_NO_SHA1 */    	
       
   101 
       
   102     if(1) {
       
   103 	xmlSecError(XMLSEC_ERRORS_HERE, 
       
   104 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   105 		    NULL,
       
   106 		    XMLSEC_ERRORS_R_INVALID_TRANSFORM,
       
   107 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   108 	return(-1);
       
   109     }
       
   110     
       
   111 #ifndef XMLSEC_GNUTLS_OLD
       
   112     ret = sc_md_open(&ctx->digestCtx, ctx->digest, SC_MD_FLAG_SECURE); /* we are paranoid */
       
   113     if(ret != KErrNone) {
       
   114 #else /* XMLSEC_GNUTLS_OLD */
       
   115     ctx->digestCtx = sc_md_open(ctx->digest, SC_MD_FLAG_SECURE); /* we are paranoid */
       
   116     if(!ctx->digestCtx) {
       
   117 #endif /* XMLSEC_GNUTLS_OLD */
       
   118     if ( ret != KErrNone )
       
   119         {
       
   120         xmlSecSetErrorFlag( ret );
       
   121         }
       
   122 	xmlSecError(XMLSEC_ERRORS_HERE, 
       
   123 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   124 		    "sc_md_open",
       
   125 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
       
   126 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   127 	return(-1);
       
   128     }
       
   129     return(0);
       
   130 }
       
   131 
       
   132 static void 
       
   133 xmlSecSymbianCryptoDigestFinalize(xmlSecTransformPtr transform) {
       
   134     xmlSecSymbianCryptoDigestCtxPtr ctx;
       
   135 
       
   136     xmlSecAssert(xmlSecSymbianCryptoDigestCheckId(transform));
       
   137     xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecSymbianCryptoDigestSize));
       
   138 
       
   139     ctx = xmlSecSymbianCryptoDigestGetCtx(transform);
       
   140     xmlSecAssert(ctx);
       
   141     
       
   142     if(ctx->digestCtx) {
       
   143 	sc_md_close(ctx->digestCtx);
       
   144     }
       
   145     memset(ctx, 0, sizeof(xmlSecSymbianCryptoDigestCtx));
       
   146 }
       
   147 
       
   148 static int
       
   149 xmlSecSymbianCryptoDigestVerify(xmlSecTransformPtr transform, 
       
   150 			const xmlSecByte* data, xmlSecSize dataSize,
       
   151 			xmlSecTransformCtxPtr transformCtx) {
       
   152     xmlSecSymbianCryptoDigestCtxPtr ctx;
       
   153     
       
   154     xmlSecAssert2(xmlSecSymbianCryptoDigestCheckId(transform), -1);
       
   155     xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1);
       
   156     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecSymbianCryptoDigestSize), -1);
       
   157     xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1);
       
   158     xmlSecAssert2(data, -1);
       
   159     xmlSecAssert2(transformCtx, -1);
       
   160 
       
   161     ctx = xmlSecSymbianCryptoDigestGetCtx(transform);
       
   162     xmlSecAssert2(ctx, -1);
       
   163     xmlSecAssert2(ctx->dgstSize > 0, -1);
       
   164     
       
   165     if(dataSize != ctx->dgstSize) {
       
   166 	xmlSecError(XMLSEC_ERRORS_HERE, 
       
   167 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   168 		    NULL,
       
   169 		    XMLSEC_ERRORS_R_INVALID_DATA,
       
   170 		    "data and digest sizes are different (data=%d, dgst=%d)", 
       
   171 		    dataSize, ctx->dgstSize);
       
   172 	transform->status = xmlSecTransformStatusFail;
       
   173 	return(0);
       
   174     }
       
   175     
       
   176     if(memcmp(ctx->dgst, data, dataSize) != 0) {
       
   177 	xmlSecError(XMLSEC_ERRORS_HERE, 
       
   178 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   179 		    NULL,
       
   180 		    XMLSEC_ERRORS_R_INVALID_DATA,
       
   181 		    "data and digest do not match");
       
   182 	transform->status = xmlSecTransformStatusFail;
       
   183 	return(0);
       
   184     }
       
   185     
       
   186     transform->status = xmlSecTransformStatusOk;
       
   187     return(0);
       
   188 }
       
   189 
       
   190 static int 
       
   191 xmlSecSymbianCryptoDigestExecute(xmlSecTransformPtr transform, 
       
   192                                         int last, 
       
   193                                         xmlSecTransformCtxPtr transformCtx) {
       
   194     xmlSecSymbianCryptoDigestCtxPtr ctx;
       
   195     xmlSecBufferPtr in, out;
       
   196     int ret;
       
   197     
       
   198     xmlSecAssert2(xmlSecSymbianCryptoDigestCheckId(transform), -1);
       
   199     xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) 
       
   200                                 || (transform->operation == xmlSecTransformOperationVerify), -1);
       
   201     xmlSecAssert2(transformCtx, -1);
       
   202     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecSymbianCryptoDigestSize), -1);
       
   203 
       
   204     ctx = xmlSecSymbianCryptoDigestGetCtx(transform);
       
   205     xmlSecAssert2(ctx, -1);
       
   206     xmlSecAssert2(ctx->digest != SC_MD_NONE, -1);
       
   207     xmlSecAssert2(ctx->digestCtx, -1);
       
   208 
       
   209     in = &(transform->inBuf);
       
   210     out = &(transform->outBuf);
       
   211 
       
   212     if(transform->status == xmlSecTransformStatusNone) {
       
   213 	transform->status = xmlSecTransformStatusWorking;
       
   214     }
       
   215     
       
   216     if(transform->status == xmlSecTransformStatusWorking) {
       
   217 	xmlSecSize inSize;
       
   218 
       
   219 	inSize = xmlSecBufferGetSize(in);
       
   220 	if(inSize > 0) {
       
   221 	    sc_md_write(ctx->digestCtx, xmlSecBufferGetData(in), inSize);
       
   222 	    
       
   223 	    ret = xmlSecBufferRemoveHead(in, inSize);
       
   224 	    if(ret < 0) {
       
   225 		xmlSecError(XMLSEC_ERRORS_HERE, 
       
   226 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   227 			    "xmlSecBufferRemoveHead",
       
   228 			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   229 			    "size=%d", inSize);
       
   230 		return(-1);
       
   231 	    }
       
   232 	}
       
   233 	if(last) {
       
   234 	    const xmlSecByte* buf;
       
   235 	    
       
   236 	    /* get the final digest */
       
   237 	    sc_md_final(ctx->digestCtx);
       
   238 	    
       
   239 	    /* get length before sc_md_read */
       
   240 	    ctx->dgstSize = sc_md_get_algo_dlen(ctx->digestCtx);
       
   241 	    xmlSecAssert2(ctx->dgstSize > 0, -1);
       
   242 	    xmlSecAssert2(ctx->dgstSize <= sizeof(ctx->dgst), -1);
       
   243 	    
       
   244 	    buf = sc_md_read(ctx->digestCtx, ctx->digest);
       
   245 	    if(!buf) {
       
   246 		xmlSecError(XMLSEC_ERRORS_HERE, 
       
   247 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   248 			    "sc_md_read",
       
   249 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
       
   250 			    XMLSEC_ERRORS_NO_MESSAGE);
       
   251 	        return(-1);
       
   252 	    }
       
   253 	    
       
   254 	    /* copy it to our internal buffer */
       
   255 	    memcpy(ctx->dgst, buf, ctx->dgstSize);
       
   256 
       
   257 	    /* and to the output if needed */
       
   258 	    if(transform->operation == xmlSecTransformOperationSign) {
       
   259 		ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize);
       
   260 		if(ret < 0) {
       
   261 		    xmlSecError(XMLSEC_ERRORS_HERE, 
       
   262 				xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   263 				"xmlSecBufferAppend",
       
   264 				XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   265 				"size=%d", ctx->dgstSize);
       
   266 		    return(-1);
       
   267 		}
       
   268 	    }
       
   269 	    transform->status = xmlSecTransformStatusFinished;
       
   270 	}
       
   271     } else if(transform->status == xmlSecTransformStatusFinished) {
       
   272 	/* the only way we can get here is if there is no input */
       
   273 	xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
       
   274     } else {
       
   275 	xmlSecError(XMLSEC_ERRORS_HERE, 
       
   276 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
       
   277 		    NULL,
       
   278 		    XMLSEC_ERRORS_R_INVALID_STATUS,
       
   279 		    "status=%d", transform->status);
       
   280 	return(-1);
       
   281     }
       
   282     
       
   283     return(0);
       
   284 }
       
   285 
       
   286 #ifndef XMLSEC_NO_SHA1
       
   287 /******************************************************************************
       
   288  *
       
   289  * SHA1 Digest transforms
       
   290  *
       
   291  *****************************************************************************/
       
   292 static xmlSecTransformKlass xmlSecSymbianCryptoSha1Klass = {
       
   293     /* klass/object sizes */
       
   294     sizeof(xmlSecTransformKlass),		/* xmlSecSize klassSize */
       
   295     xmlSecSymbianCryptoDigestSize,			/* xmlSecSize objSize */
       
   296 
       
   297     /* data */
       
   298     xmlSecNameSha1,						/* const xmlChar* name; */
       
   299     xmlSecHrefSha1, 						/* const xmlChar* href; */
       
   300     xmlSecTransformUsageDigestMethod,		/* xmlSecTransformUsage usage; */
       
   301     
       
   302     /* methods */
       
   303     xmlSecSymbianCryptoDigestInitialize,		/* xmlSecTransformInitializeMethod initialize; */
       
   304     xmlSecSymbianCryptoDigestFinalize,			/* xmlSecTransformFinalizeMethod finalize; */
       
   305     NULL,					/* xmlSecTransformNodeReadMethod readNode; */
       
   306     NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */
       
   307     NULL,					/* xmlSecTransformSetKeyReqMethod setKeyReq; */
       
   308     NULL,					/* xmlSecTransformSetKeyMethod setKey; */
       
   309     xmlSecSymbianCryptoDigestVerify,			/* xmlSecTransformVerifyMethod verify; */
       
   310     xmlSecCrpytoGetDataTypeMethod,		/* xmlSecTransformGetDataTypeMethod getDataType; */
       
   311     xmlSecCryptoPushBinMethod,		/* xmlSecTransformPushBinMethod pushBin; */
       
   312     xmlSecCryptoPopBinMethod,		/* xmlSecTransformPopBinMethod popBin; */
       
   313     NULL,					/* xmlSecTransformPushXmlMethod pushXml; */
       
   314     NULL,					/* xmlSecTransformPopXmlMethod popXml; */
       
   315     xmlSecSymbianCryptoDigestExecute,			/* xmlSecTransformExecuteMethod execute; */
       
   316     
       
   317     NULL,					/* void* reserved0; */
       
   318     NULL,					/* void* reserved1; */
       
   319 };
       
   320 
       
   321 /** 
       
   322  * xmlSecSymbianCryptoTransformSha1GetKlass:
       
   323  *
       
   324  * SHA-1 digest transform klass.
       
   325  *
       
   326  * Returns pointer to SHA-1 digest transform klass.
       
   327  */
       
   328 EXPORT_C
       
   329 xmlSecTransformId 
       
   330 xmlSecSymbianCryptoTransformSha1GetKlass(void) {
       
   331     return(&xmlSecSymbianCryptoSha1Klass);
       
   332 }
       
   333 #endif /* XMLSEC_NO_SHA1 */
       
   334 
       
   335 
       
   336 
       
   337