r3107 - in trunk/libmikey: include/libmikey mikey

erik at minisip.org erik at minisip.org
Wed Jan 10 21:28:33 CET 2007


Author: erik
Date: 2007-01-10 21:28:32 +0100 (Wed, 10 Jan 2007)
New Revision: 3107

Modified:
   trunk/libmikey/include/libmikey/MikeyPayloadSIGN.h
   trunk/libmikey/mikey/MikeyMessage.cxx
   trunk/libmikey/mikey/MikeyPayloadSIGN.cxx
Log:

 * Signature calculation was done twice for every
   MIKEY message. The first was only to find out
   the length of the signature, and the second
   was needed because that length is included in
   what is signed.

    -> I changed so that MikeyPayloadSIGN does not
      take the signature as parameter (it can not
      be calculated until after the payload has been
      added - it made little sence).

    -> Now the code guesses that the signature will
      be 1024 bits long, and the second signing is
      only done if that was not correct.

   If the certificate class has a method to find out
   the length of the signature before actually doing
   the signing, then there would not be this
   performance penalty (~2x) for having other key sizes.




Modified: trunk/libmikey/include/libmikey/MikeyPayloadSIGN.h
===================================================================
--- trunk/libmikey/include/libmikey/MikeyPayloadSIGN.h	2007-01-10 19:53:22 UTC (rev 3106)
+++ trunk/libmikey/include/libmikey/MikeyPayloadSIGN.h	2007-01-10 20:28:32 UTC (rev 3107)
@@ -40,7 +40,7 @@
 class LIBMIKEY_API MikeyPayloadSIGN : public MikeyPayload{
 	public:
 	
-		MikeyPayloadSIGN( int sigLength, byte_t * data, int type );
+		MikeyPayloadSIGN( int sigLength, int type );
 		MikeyPayloadSIGN( byte_t * start, int lengthLimit );
 		~MikeyPayloadSIGN();
 
@@ -52,7 +52,7 @@
 		byte_t * sigData();
 		int sigType();
 
-		void setSigData( byte_t * data );
+		void setSigData( byte_t * data, int sigLength);
 
 	private:
 		int sigTypeValue;

Modified: trunk/libmikey/mikey/MikeyMessage.cxx
===================================================================
--- trunk/libmikey/mikey/MikeyMessage.cxx	2007-01-10 19:53:22 UTC (rev 3106)
+++ trunk/libmikey/mikey/MikeyMessage.cxx	2007-01-10 20:28:32 UTC (rev 3107)
@@ -58,6 +58,10 @@
 #include"MikeyMessageDHHMAC.h"
 #include"MikeyMessageRSAR.h"
 
+/// The signature calculation will be factor two faster if this 
+/// guess is correct (128 bytes == 1024 bits)
+#define GUESSED_SIGNATURE_LENGTH 128
+
 using namespace std;
 
 
@@ -312,7 +316,7 @@
 
 void MikeyPayloads::addSignaturePayload( MRef<SipSim*> sim ){
 	byte_t signature[4096];
-	int signatureLength;
+	int signatureLength=4096;
 	MikeyPayloadSIGN * sign;
 	MRef<MikeyPayload*> last;
 	
@@ -320,25 +324,35 @@
 	last = *lastPayload();
 	last->setNextPayloadType( MIKEYPAYLOAD_SIGN_PAYLOAD_TYPE );
 
-	if( !sim->getSignature( (unsigned char*)rawMessageData(), (int)rawMessageLength(),
-			 (unsigned char*)signature, signatureLength, true ) ){
+	// See the comment in addSignaturePayload(cert) for explanation of
+	// the following steps.
+
+	addPayload( ( sign = new MikeyPayloadSIGN( GUESSED_SIGNATURE_LENGTH, 
+						   MIKEYPAYLOAD_SIGN_TYPE_RSA_PKCS ) ) );
+
+	if (!sim->getSignature( rawMessageData(), 
+			 rawMessageLength() - GUESSED_SIGNATURE_LENGTH,
+			 signature, signatureLength, true )){
 		throw MikeyException( "Could not perform digital signature of the message" );
 	}
 
-	addPayload( ( sign = new MikeyPayloadSIGN( signatureLength, signature,
-				MIKEYPAYLOAD_SIGN_TYPE_RSA_PKCS ) ) );
+	if (signatureLength!=GUESSED_SIGNATURE_LENGTH){	// if the length field in the signature payload was 
+							// wrong, we have to redo the signature
+		sign->setSigData(signature, signatureLength); // the length needs to be set to the correct value
 
-	sim->getSignature( rawMessageData(), 
-			 rawMessageLength() - signatureLength,
-			 signature, signatureLength, true );
-	sign->setSigData( signature );
+		sim->getSignature( rawMessageData(), 
+				rawMessageLength() - signatureLength,
+				signature, signatureLength, true );
+	}
+
+	sign->setSigData( signature, signatureLength );
 	compiled = false;
 }
 
 
 void MikeyPayloads::addSignaturePayload( MRef<certificate *> cert ){
 	byte_t signature[4096];
-	int signatureLength = sizeof(signature);
+	int signatureLength = 128;
 	MikeyPayloadSIGN * sign;
 	MRef<MikeyPayload*> last;
 	
@@ -346,18 +360,38 @@
 	last = *lastPayload();
 	last->setNextPayloadType( MIKEYPAYLOAD_SIGN_PAYLOAD_TYPE );
 
-	if( cert->sign_data( rawMessageData(), rawMessageLength(),
-			 signature, &signatureLength ) ){
+	//The SIGN payload constructor can not take the signature as
+	//parameter. This is because it can not be computed before
+	//the SIGN payload has been added to the MIKEY message (the next
+	//payload field in the payload before SIGN is not set).
+	//
+	//We guess that the length of the signature is 1024 bits. We then
+	//calculate the signature, and if it turns out that it was not
+	//1024, we have to re-do the signature calculation with the correct
+	//length.
+	//
+	//Double-signatures would be avoided if the certificate had a 
+	//method to find out the length of the signature.
+	
+	addPayload( ( sign = new MikeyPayloadSIGN(GUESSED_SIGNATURE_LENGTH, MIKEYPAYLOAD_SIGN_TYPE_RSA_PKCS ) ) );
+
+	if (cert->sign_data( rawMessageData(), 
+			 rawMessageLength() - GUESSED_SIGNATURE_LENGTH,
+			 signature, &signatureLength )){
 		throw MikeyException( "Could not perform digital signature of the message" );
 	}
 
-	addPayload( ( sign = new MikeyPayloadSIGN( signatureLength, signature,
-				MIKEYPAYLOAD_SIGN_TYPE_RSA_PKCS ) ) );
 
-	cert->sign_data( rawMessageData(), 
-			 rawMessageLength() - signatureLength,
-			 signature, &signatureLength );
-	sign->setSigData( signature );
+	if (signatureLength!=GUESSED_SIGNATURE_LENGTH){	// if the length field in the signature payload was 
+							// wrong, we have to redo the signature
+		sign->setSigData(signature, signatureLength); // the length needs to be set to the correct value
+
+		cert->sign_data( rawMessageData(), 
+				rawMessageLength() - signatureLength,
+				signature, &signatureLength );
+	}
+
+	sign->setSigData( signature, signatureLength ); // the payload signature is a dummy value until we do this
 	compiled = false;
 }
 

Modified: trunk/libmikey/mikey/MikeyPayloadSIGN.cxx
===================================================================
--- trunk/libmikey/mikey/MikeyPayloadSIGN.cxx	2007-01-10 19:53:22 UTC (rev 3106)
+++ trunk/libmikey/mikey/MikeyPayloadSIGN.cxx	2007-01-10 20:28:32 UTC (rev 3107)
@@ -30,7 +30,7 @@
 
 using namespace std;
 
-MikeyPayloadSIGN::MikeyPayloadSIGN( int sigLengthValue, byte_t * sigDataPtr,
+MikeyPayloadSIGN::MikeyPayloadSIGN( int sigLengthValue,
 				    int type){
 
 	this->payloadTypeValue = MIKEYPAYLOAD_SIGN_PAYLOAD_TYPE;
@@ -38,12 +38,7 @@
 	                         // this value
 	this->sigLengthValue = sigLengthValue;
 	this->sigDataPtr = new byte_t[ sigLengthValue ];
-	if( sigDataPtr ){
-		memcpy( this->sigDataPtr, sigDataPtr, sigLengthValue );
-	}
-	else{
-		memset( this->sigDataPtr, 0, sigLengthValue );
-	}
+	memset( this->sigDataPtr, 0, sigLengthValue );
 	this->sigTypeValue = type;
 
 }
@@ -110,10 +105,11 @@
 	return sigTypeValue;
 }
 
-void MikeyPayloadSIGN::setSigData( byte_t * data ){
+void MikeyPayloadSIGN::setSigData( byte_t * data, int len ){
 	if( sigDataPtr )
 		delete [] sigDataPtr;
 
+	sigLengthValue = len;
 	sigDataPtr = new byte_t[ sigLengthValue ];
 	memcpy( sigDataPtr, data, sigLengthValue );
 }



More information about the Minisip-devel mailing list