r3089 - in trunk/libmikey: . include/libmikey keyagreement mikey

mikma at minisip.org mikma at minisip.org
Thu Jan 4 22:37:22 CET 2007


Author: mikma
Date: 2007-01-04 22:37:21 +0100 (Thu, 04 Jan 2007)
New Revision: 3089

Added:
   trunk/libmikey/include/libmikey/KeyAgreementRSAR.h
   trunk/libmikey/keyagreement/KeyAgreementRSAR.cxx
   trunk/libmikey/mikey/MikeyMessageRSAR.cxx
   trunk/libmikey/mikey/MikeyMessageRSAR.h
Modified:
   trunk/libmikey/Makefile.am
   trunk/libmikey/include/libmikey/MikeyMessage.h
   trunk/libmikey/mikey/MikeyMessage.cxx
   trunk/libmikey/mikey/MikeyMessagePKE.cxx
   trunk/libmikey/mikey/MikeyPayloadHDR.cxx
Log:
Add MIKEY RSA-R implementation to libmikey

Modified: trunk/libmikey/Makefile.am
===================================================================
--- trunk/libmikey/Makefile.am	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/Makefile.am	2007-01-04 21:37:21 UTC (rev 3089)
@@ -31,6 +31,8 @@
                      mikey/MikeyMessageDHHMAC.cxx \
                      mikey/MikeyMessagePKE.h \
                      mikey/MikeyMessagePKE.cxx \
+                     mikey/MikeyMessageRSAR.h \
+                     mikey/MikeyMessageRSAR.cxx \
                      mikey/MikeyPayloadCERT.cxx \
                      mikey/MikeyPayloadCHASH.cxx \
                      mikey/MikeyPayload.cxx \
@@ -53,6 +55,7 @@
 	             keyagreement/keyagreement_psk.cxx \
 	             keyagreement/KeyAgreementPKE.cxx \
 	             keyagreement/KeyAgreementDHHMAC.cxx \
+	             keyagreement/KeyAgreementRSAR.cxx \
 		     keyagreement/keyvalidity.cxx
 
 # maintainer rules

Added: trunk/libmikey/include/libmikey/KeyAgreementRSAR.h
===================================================================
--- trunk/libmikey/include/libmikey/KeyAgreementRSAR.h	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/include/libmikey/KeyAgreementRSAR.h	2007-01-04 21:37:21 UTC (rev 3089)
@@ -0,0 +1,47 @@
+/*
+  Copyright (C) 2006 Mikael Magnusson
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Authors: Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+#ifndef KEYAGREEMENTRSAR_H
+#define KEYAGREEMENTRSAR_H
+
+#include <libmikey/KeyAgreementPKE.h>
+#include <libmcrypto/cert.h>
+
+/**
+ * Instances of this class are used to store the necessary information about
+ * the keys used in the security protocol SRTP
+ * It contains the necessary methods to derive the keys used
+ */
+class KeyAgreementRSAR : public KeyAgreementPKE{
+	public:
+	
+		KeyAgreementRSAR( MRef<certificate_chain *> cert, 
+				  MRef<ca_db *> ca_db );
+	    
+		/**
+		 * Destructor deletes some objects to prevent memory leaks
+		 */
+		~KeyAgreementRSAR();
+	    
+		MikeyMessage* createMessage();
+};
+#endif //KEYAGREEMENTRSAR_H


Property changes on: trunk/libmikey/include/libmikey/KeyAgreementRSAR.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Modified: trunk/libmikey/include/libmikey/MikeyMessage.h
===================================================================
--- trunk/libmikey/include/libmikey/MikeyMessage.h	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/include/libmikey/MikeyMessage.h	2007-01-04 21:37:21 UTC (rev 3089)
@@ -70,6 +70,7 @@
 class certificate_db;
 class KeyAgreementDHHMAC;
 class KeyAgreementPKE;
+class KeyAgreementRSAR;
 
 class LIBMIKEY_API MikeyPayloads{
 	public:
@@ -99,6 +100,8 @@
 		void addCertificatePayloads( MRef<certificate_chain *> certChain );
 		MRef<certificate_chain*> extractCertificateChain() const;
 
+		void addPkeKemac( KeyAgreementPKE* ka,
+				  int encrAlg, int macAlg );
 		bool extractPkeEnvKey( KeyAgreementPKE* ka ) const;
 
 		std::string debugDump();
@@ -137,6 +140,14 @@
 				const byte_t* macInput,
 				unsigned int macInputLength ) const;
 
+		/** Derive the transport keys from the env_key and set ka auth key */
+		bool deriveTranspKeys( KeyAgreementPSK* ka,
+				       byte_t*& encrKey, byte_t *& iv,
+				       unsigned int& encrKeyLength,
+				       int encrAlg, int macAlg,
+				       uint64_t t,
+				       MikeyMessage* errorMessage );
+
 		std::list<MikeyPayload *> payloads;
 
 	private:
@@ -166,6 +177,7 @@
 		static MikeyMessage* create(KeyAgreementPKE* ka,
 				  int encrAlg = MIKEY_ENCR_AES_CM_128,
 					    int macAlg = MIKEY_MAC_HMAC_SHA1_160 );
+		static MikeyMessage* create(KeyAgreementRSAR* ka);
 
 		/**
 		 * Parse MIKEY message from binary representation
@@ -189,15 +201,6 @@
 		virtual bool isResponderMessage() const;
 		virtual int32_t keyAgreementType() const;
 
-	protected:
-		/** Derive the transport keys from the env_key and set ka auth key */
-		bool deriveTranspKeys( KeyAgreementPSK* ka,
-				       byte_t*& encrKey, byte_t *& iv,
-				       unsigned int& encrKeyLength,
-				       int encrAlg, int macAlg,
-				       uint64_t t,
-				       MikeyMessage* errorMessage );
-
 	private:
 };
 

Added: trunk/libmikey/keyagreement/KeyAgreementRSAR.cxx
===================================================================
--- trunk/libmikey/keyagreement/KeyAgreementRSAR.cxx	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/keyagreement/KeyAgreementRSAR.cxx	2007-01-04 21:37:21 UTC (rev 3089)
@@ -0,0 +1,40 @@
+/*
+  Copyright (C) 2006 Mikael Magnusson
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Authors: Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+#include <config.h>
+
+#include <libmikey/KeyAgreementRSAR.h>
+#include <libmikey/MikeyMessage.h>
+
+
+KeyAgreementRSAR::KeyAgreementRSAR( MRef<certificate_chain *> cert, 
+				    MRef<ca_db *> ca_db )
+		:KeyAgreementPKE(cert, ca_db)
+{
+}
+
+KeyAgreementRSAR::~KeyAgreementRSAR(){
+}
+
+MikeyMessage* KeyAgreementRSAR::createMessage(){
+	return MikeyMessage::create( this );
+}


Property changes on: trunk/libmikey/keyagreement/KeyAgreementRSAR.cxx
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Modified: trunk/libmikey/mikey/MikeyMessage.cxx
===================================================================
--- trunk/libmikey/mikey/MikeyMessage.cxx	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/mikey/MikeyMessage.cxx	2007-01-04 21:37:21 UTC (rev 3089)
@@ -56,6 +56,7 @@
 #include"MikeyMessagePSK.h"
 #include"MikeyMessagePKE.h"
 #include"MikeyMessageDHHMAC.h"
+#include"MikeyMessageRSAR.h"
 
 using namespace std;
 
@@ -92,6 +93,10 @@
 	return new MikeyMessagePKE( ka, encrAlg, macAlg );
 }
 
+MikeyMessage* MikeyMessage::create( KeyAgreementRSAR* ka ){
+	return new MikeyMessageRSAR( ka );
+}
+
 /*
  * Alg.
  *  1. Parse HDR payload
@@ -134,6 +139,10 @@
 		case MIKEY_TYPE_DHHMAC_RESP:
 			msg = new MikeyMessageDHHMAC();
 			break;
+		case MIKEY_TYPE_RSA_R_INIT:
+		case MIKEY_TYPE_RSA_R_RESP:
+			msg = new MikeyMessageRSAR();
+			break;
 		case MIKEY_TYPE_ERROR:
 			msg = new MikeyMessage();
 			break;
@@ -687,7 +696,7 @@
 		"Unimplemented type of MIKEY message" );
 }
 
-bool MikeyMessage::deriveTranspKeys( KeyAgreementPSK* ka,
+bool MikeyPayloads::deriveTranspKeys( KeyAgreementPSK* ka,
 					byte_t*& encrKey, byte_t *& iv,
 					unsigned int& encrKeyLength,
 					int encrAlg, int macAlg,
@@ -933,6 +942,65 @@
 	}
 }
 
+void MikeyPayloads::addPkeKemac( KeyAgreementPKE* ka,
+				    int encrAlg, int macAlg ){
+
+	// Derive the transport keys from the env_key:
+	byte_t* encrKey = NULL;
+	byte_t* iv = NULL;
+	unsigned int encrKeyLength = 0;
+	
+	deriveTranspKeys( ka, encrKey, iv, encrKeyLength,
+			  encrAlg, macAlg, ka->tSent(),
+			  NULL );
+
+	//adding KEMAC payload
+	MikeyPayloads* subPayloads = new MikeyPayloads();
+	MikeyPayloadKeyData* keydata = 
+		new MikeyPayloadKeyData(KEYDATA_TYPE_TGK, ka->tgk(),
+							ka->tgkLength(), ka->keyValidity());
+	// FIXME get uri from certificate.
+	const char uri[] = "sip:test";
+	MikeyPayloadID* initId =
+		new MikeyPayloadID( MIKEYPAYLOAD_ID_TYPE_URI, strlen( uri ), (byte_t*)uri );
+
+	subPayloads->addPayload( initId );
+ 	subPayloads->addPayload( keydata );
+	initId = NULL;
+	keydata = NULL;
+
+	unsigned int rawKeyDataLength = subPayloads->rawMessageLength();
+	byte_t* rawKeyData = new byte_t[ rawKeyDataLength ];
+	memcpy( rawKeyData, subPayloads->rawMessageData(), rawKeyDataLength );
+
+	addKemacPayload(rawKeyData, rawKeyDataLength,
+			encrKey, iv, ka->authKey, encrAlg, macAlg, true );
+
+	delete subPayloads;
+	subPayloads = NULL;
+
+ 	delete [] rawKeyData;
+	rawKeyData = NULL;
+
+	//adding PKE payload
+	MRef<certificate*> certResponder =
+		ka->peerCertificateChain()->get_first();
+
+	byte_t* env_key = ka->getEnvelopeKey();
+	int encEnvKeyLength = 8192; // TODO autodetect?
+	unsigned char* encEnvKey = new unsigned char[ encEnvKeyLength ];
+
+	if( !certResponder->public_encrypt( env_key, ka->getEnvelopeKeyLength(),
+					    encEnvKey, &encEnvKeyLength ) ){
+		throw MikeyException( "PKE encryption of envelope key failed" );
+	}
+
+	addPayload(new MikeyPayloadPKE(2, encEnvKey, encEnvKeyLength));
+
+ 	delete [] encEnvKey;
+	encEnvKey = NULL;
+}
+
 bool MikeyPayloads::extractPkeEnvKey( KeyAgreementPKE* ka ) const{
 	const MikeyPayload *payloadPke =
 		extractPayload( MIKEYPAYLOAD_PKE_PAYLOAD_TYPE );

Modified: trunk/libmikey/mikey/MikeyMessagePKE.cxx
===================================================================
--- trunk/libmikey/mikey/MikeyMessagePKE.cxx	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/mikey/MikeyMessagePKE.cxx	2007-01-04 21:37:21 UTC (rev 3089)
@@ -51,6 +51,12 @@
 	MikeyPayloadT* tPayload;
 	MikeyPayloadRAND* randPayload;
 
+	MRef<certificate_chain*> peerChain =
+		ka->peerCertificateChain();
+	if( !peerChain || !peerChain->get_first() ){
+		throw MikeyException( "PKE requires peer certificate" );
+	}
+
 	//adding header payload
 	addPayload(new MikeyPayloadHDR(HDR_DATA_TYPE_PK_INIT, 1, 
 											HDR_PRF_MIKEY_1, csbId, ka->nCs(),
@@ -76,69 +82,9 @@
 	addCertificatePayloads( ka->certificateChain() );
 
 	// Derive the transport keys from the env_key:
-	byte_t* encrKey = NULL;
-	byte_t* iv = NULL;
-	unsigned int encrKeyLength = 0;
-	
-	deriveTranspKeys( ka, encrKey, iv, encrKeyLength,
-			  encrAlg, macAlg, t,
-			  NULL );
+	addPkeKemac( ka, encrAlg, macAlg );
 
-	//adding KEMAC payload
-	MikeyPayloads* subPayloads = new MikeyPayloads();
-	MikeyPayloadKeyData* keydata = 
-		new MikeyPayloadKeyData(KEYDATA_TYPE_TGK, ka->tgk(),
-							ka->tgkLength(), ka->keyValidity());
-	// FIXME get uri from certificate.
-	const char uri[] = "sip:test";
-	MikeyPayloadID* initId =
-		new MikeyPayloadID( MIKEYPAYLOAD_ID_TYPE_URI, strlen( uri ), (byte_t*)uri );
-
-	subPayloads->addPayload( initId );
-	subPayloads->addPayload( keydata );
-	initId = NULL;
-	keydata = NULL;
-
-	unsigned int rawKeyDataLength = subPayloads->rawMessageLength();
-	byte_t* rawKeyData = new byte_t[ rawKeyDataLength ];
-	memcpy( rawKeyData, subPayloads->rawMessageData(), rawKeyDataLength );
-	
-	addKemacPayload(rawKeyData, rawKeyDataLength,
-			encrKey, iv, ka->authKey, encrAlg, macAlg, true );
-
-	delete subPayloads;
-	subPayloads = NULL;
-
-	//adding PKE payload
-	MRef<certificate*> certResponder =
-		ka->peerCertificateChain()->get_first();
-
-	if( !certResponder ){
-		throw MikeyException( "PKE requires peer certificate" );
-	}
-
-	byte_t* env_key = ka->getEnvelopeKey();
-	int encEnvKeyLength = 8192; // TODO autodetect?
-	unsigned char* encEnvKey = new unsigned char[ encEnvKeyLength ];
-
-	if( !certResponder->public_encrypt( env_key, ka->getEnvelopeKeyLength(),
-					    encEnvKey, &encEnvKeyLength ) ){
-		throw MikeyException( "PKE encryption of envelope key failed" );
-	}
-
-	addPayload(new MikeyPayloadPKE(2, encEnvKey, encEnvKeyLength));
-	
 	addSignaturePayload( ka->certificateChain()->get_first() );
-
-	//remove garbage
-	if( encrKey != NULL )
-		delete [] encrKey;
-
-	if( iv != NULL )
-		delete [] iv;
-	
-	delete [] rawKeyData;
-	delete [] encEnvKey;
 }
 
 void MikeyMessagePKE::setOffer(KeyAgreement* kaBase){

Copied: trunk/libmikey/mikey/MikeyMessageRSAR.cxx (from rev 3088, trunk/libmikey/mikey/MikeyMessagePKE.cxx)
===================================================================
--- trunk/libmikey/mikey/MikeyMessagePKE.cxx	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/mikey/MikeyMessageRSAR.cxx	2007-01-04 21:37:21 UTC (rev 3089)
@@ -0,0 +1,449 @@
+
+/*
+  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien, Joachim Orrblad
+  Copyright (C) 2006 Mikael Magnusson
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ *          Johan Bilien <jobi at via.ecp.fr>
+ *	    Joachim Orrblad <joachim at orrblad.com>
+ *          Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+#include <config.h>
+
+#include "MikeyMessageRSAR.h"
+#include <libmikey/MikeyPayloadHDR.h>
+#include <libmikey/MikeyPayloadT.h>
+#include <libmikey/MikeyPayloadRAND.h>
+#include <libmikey/MikeyException.h>
+#include <libmikey/MikeyPayloadCERT.h>
+#include <libmikey/MikeyPayloadKeyData.h>
+#include <libmikey/MikeyPayloadERR.h>
+#include <libmikey/MikeyPayloadID.h>
+#include <libmikey/MikeyPayloadKEMAC.h>
+#include <libmikey/MikeyPayloadV.h>
+#include <libmikey/MikeyPayloadPKE.h>
+
+using namespace std;
+
+MikeyMessageRSAR::MikeyMessageRSAR(){
+}
+
+MikeyMessageRSAR::MikeyMessageRSAR( KeyAgreementRSAR* ka ){
+
+	unsigned int csbId = rand();
+	ka->setCsbId(csbId);
+	MikeyPayloadT* tPayload;
+	MikeyPayloadRAND* randPayload;
+
+	//adding header payload
+	addPayload(new MikeyPayloadHDR(HDR_DATA_TYPE_RSA_R_INIT, 1, 
+											HDR_PRF_MIKEY_1, csbId, ka->nCs(),
+											ka->getCsIdMapType(), ka->csIdMap()));
+
+	//adding timestamp payload
+	addPayload(tPayload = new MikeyPayloadT());
+
+	//adding security policy
+	addPolicyToPayload(ka); //Is in MikeyMessage.cxx
+
+	//keep a copy of the time stamp
+	uint64_t t = tPayload->ts();
+	ka->setTSent(t);
+
+	//adding random payload
+	addPayload(randPayload = new MikeyPayloadRAND());
+	
+	//keep a copy of the random value
+	ka->setRand(randPayload->randData(), randPayload->randLength());
+
+	// Add certificate chain (SIGN)
+	addCertificatePayloads( ka->certificateChain() );
+
+	// Add signature (T)
+	addSignaturePayload( ka->certificateChain()->get_first() );
+}
+
+void MikeyMessageRSAR::setOffer(KeyAgreement* kaBase){
+	KeyAgreementRSAR* ka = dynamic_cast<KeyAgreementRSAR*>(kaBase);
+
+	if( !ka ){
+		throw MikeyExceptionMessageContent( 
+				"Not a RSAR keyagreement" );
+	}
+
+	MikeyPayload* i = extractPayload( MIKEYPAYLOAD_HDR_PAYLOAD_TYPE );
+	bool error = false;
+	//uint32_t csbId;
+	MRef<MikeyCsIdMap*> csIdMap;
+	MikeyMessage* errorMessage = new MikeyMessage();
+	//uint8_t nCs;
+
+	if( i == NULL || 
+		i->payloadType() != MIKEYPAYLOAD_HDR_PAYLOAD_TYPE ){
+		throw MikeyExceptionMessageContent( 
+				"RSAR init message had no HDR payload" );
+	}
+
+#define hdr ((MikeyPayloadHDR *)(i))
+	if( hdr->dataType() != HDR_DATA_TYPE_RSA_R_INIT ){
+		throw MikeyExceptionMessageContent( 
+				"Expected RSAR init message" );
+	}
+
+	ka->setnCs( hdr->nCs() );
+	ka->setCsbId( hdr->csbId() );
+	ka->setV(hdr->v());
+
+	if( hdr->csIdMapType() == HDR_CS_ID_MAP_TYPE_SRTP_ID || hdr->csIdMapType() == HDR_CS_ID_MAP_TYPE_IPSEC4_ID ){
+		ka->setCsIdMap( hdr->csIdMap() );
+		ka->setCsIdMapType( hdr->csIdMapType() );
+	}
+	else{
+		throw MikeyExceptionMessageContent( 
+				"Unknown type of CS ID map" );
+	}
+	
+
+#undef hdr
+	errorMessage->addPayload(
+			new MikeyPayloadHDR( HDR_DATA_TYPE_ERROR, 0,
+			HDR_PRF_MIKEY_1, ka->csbId(),
+			ka->nCs(), ka->getCsIdMapType(), 
+			ka->csIdMap() ) );
+
+	//FIXME look at the other fields!
+
+	remove( i );
+	i = extractPayload( MIKEYPAYLOAD_T_PAYLOAD_TYPE );
+
+	if( i == NULL )
+		throw MikeyExceptionMessageContent( 
+				"RSAR init message had no T payload" );
+
+	// FIXME i can be NULL
+	if( ((MikeyPayloadT*)i)->checkOffset( MAX_TIME_OFFSET ) ){
+		error = true;
+		errorMessage->addPayload( 
+			new MikeyPayloadERR( MIKEY_ERR_TYPE_INVALID_TS ) );
+	}	
+
+	ka->t_received = ((MikeyPayloadT*)i)->ts();
+	
+	remove( i );
+
+	addPolicyTo_ka(ka); //Is in MikeyMessage.cxx
+
+	i = extractPayload( MIKEYPAYLOAD_RAND_PAYLOAD_TYPE );
+
+	if( i == NULL ){
+		error = true;
+		errorMessage->addPayload( 
+			new MikeyPayloadERR( MIKEY_ERR_TYPE_UNSPEC ) );
+	}	
+
+	// FIXME i can be NULL
+	ka->setRand( ((MikeyPayloadRAND *)i)->randData(),
+			((MikeyPayloadRAND *)i)->randLength() );
+
+	remove( i );
+	i = extractPayload( MIKEYPAYLOAD_ID_PAYLOAD_TYPE );
+
+	//FIXME treat the case of an ID payload
+	if( i != NULL ){
+		remove( i );
+	}
+
+}
+
+MikeyMessage* MikeyMessageRSAR::buildResponse(KeyAgreement* kaBase){
+	KeyAgreementRSAR* ka = dynamic_cast<KeyAgreementRSAR*>(kaBase);
+
+	if( !ka ){
+		throw MikeyExceptionMessageContent( 
+				"Not a RSAR keyagreement" );
+	}
+	
+	// Build the response message
+	MikeyMessageRSAR * result = new MikeyMessageRSAR();
+	result->addPayload( 
+			   new MikeyPayloadHDR( HDR_DATA_TYPE_RSA_R_RESP, 0, 
+						HDR_PRF_MIKEY_1, ka->csbId(),
+						ka->nCs(), ka->getCsIdMapType(), 
+						ka->csIdMap() ) );
+
+	MikeyPayloadT* tPayload = new MikeyPayloadT();
+	result->addPayload( tPayload );
+
+	//keep a copy of the time stamp
+	uint64_t t = tPayload->ts();
+	ka->setTSent(t);
+
+	//adding random payload
+	MikeyPayloadRAND* randPayload = NULL;
+	result->addPayload(randPayload = new MikeyPayloadRAND());
+
+	// Add certificate chain
+	result->addCertificatePayloads( ka->certificateChain() );
+
+	// TODO move encrAlg and macAlg to method or ctor parameter
+	int encrAlg = MIKEY_ENCR_AES_CM_128;
+	int macAlg = MIKEY_MAC_HMAC_SHA1_160;
+
+	result->addPkeKemac( ka, encrAlg, macAlg );
+
+	result->addSignaturePayload( ka->certificateChain()->get_first() );
+
+	return result;
+}
+
+MikeyMessage * MikeyMessageRSAR::parseResponse( KeyAgreement * kaBase ){
+	KeyAgreementRSAR* ka = dynamic_cast<KeyAgreementRSAR*>(kaBase);
+
+	if( !ka ){
+		throw MikeyExceptionMessageContent( 
+				"Not a RSAR keyagreement" );
+	}
+
+	MikeyPayload * i = extractPayload( MIKEYPAYLOAD_HDR_PAYLOAD_TYPE );
+	bool error = false;
+	MikeyMessage * errorMessage = new MikeyMessage();
+	MRef<MikeyCsIdMap *> csIdMap;
+	uint8_t nCs;
+	
+	if( i == NULL ||
+		i->payloadType() != MIKEYPAYLOAD_HDR_PAYLOAD_TYPE ){
+
+		throw MikeyExceptionMessageContent( 
+				"RSAR response message had no HDR payload" );
+	}
+
+#define hdr ((MikeyPayloadHDR *)(i))
+	if( hdr->dataType() != HDR_DATA_TYPE_RSA_R_RESP )
+		throw MikeyExceptionMessageContent( 
+				"Expected RSAR response message" );
+
+	if( hdr->csIdMapType() == HDR_CS_ID_MAP_TYPE_SRTP_ID || hdr->csIdMapType() == HDR_CS_ID_MAP_TYPE_IPSEC4_ID){
+		csIdMap = hdr->csIdMap();
+	}
+	else{
+		throw MikeyExceptionMessageContent( 
+				"Unknown type of CS ID map" );
+	}
+
+	nCs = hdr->nCs();
+#undef hdr
+	ka->setCsIdMap( csIdMap );
+
+	errorMessage->addPayload(
+			new MikeyPayloadHDR( HDR_DATA_TYPE_ERROR, 0,
+			HDR_PRF_MIKEY_1, ka->csbId(),
+			nCs, HDR_CS_ID_MAP_TYPE_SRTP_ID,
+			csIdMap ) );
+
+
+	remove( i );
+	i = extractPayload( MIKEYPAYLOAD_T_PAYLOAD_TYPE );
+
+	if( i == NULL ){
+		error = true;
+		errorMessage->addPayload( 
+			new MikeyPayloadERR( MIKEY_ERR_TYPE_UNSPEC ) );
+	}	
+
+	// FIXME i can be NULL
+	if( ((MikeyPayloadT*)i)->checkOffset( MAX_TIME_OFFSET ) ){
+		error = true;
+		errorMessage->addPayload( 
+			new MikeyPayloadERR( MIKEY_ERR_TYPE_INVALID_TS ) );
+	}	
+
+	uint64_t t_received = ((MikeyPayloadT*)i)->ts();
+
+	i = extractPayload( MIKEYPAYLOAD_KEMAC_PAYLOAD_TYPE );
+
+	if( i == NULL ){
+		error = true;
+		errorMessage->addPayload( 
+			new MikeyPayloadERR( MIKEY_ERR_TYPE_UNSPEC ) );
+	}	
+
+	// FIXME handle i == NULL
+#define kemac ((MikeyPayloadKEMAC *)i)
+	int encrAlg = kemac->encrAlg();
+	int macAlg  = kemac->macAlg();
+	ka->macAlg = macAlg;
+
+	// Derive the transport keys
+	byte_t * encrKey=NULL;
+	byte_t * iv=NULL;
+	unsigned int encrKeyLength = 0;
+	
+	if( !deriveTranspKeys( ka, encrKey, iv, encrKeyLength,
+			      encrAlg, macAlg, t_received,
+			      errorMessage ) ){
+		if( encrKey != NULL )
+			delete [] encrKey;
+		if( iv != NULL )
+			delete [] iv;
+
+		unsigned int authKeyLength = 20;
+		byte_t* authKey = new byte_t[ authKeyLength ];
+		ka->genTranspAuthKey( authKey, authKeyLength );
+		
+		errorMessage->addVPayload( MIKEY_MAC_HMAC_SHA1_160, 
+				ka->t_received, authKey, authKeyLength  );
+		
+		delete [] authKey;
+		throw MikeyExceptionMessageContent( errorMessage );
+	}
+	
+	// decrypt the TGK
+	MikeyPayloads* subPayloads = 
+		kemac->decodePayloads( MIKEYPAYLOAD_ID_PAYLOAD_TYPE,
+				 encrKey, encrKeyLength, iv );
+	
+	if( encrKey != NULL ){
+		delete [] encrKey;
+		encrKey = NULL;
+	}
+	if( iv != NULL ){
+		delete [] iv;
+		iv = NULL;
+	}
+
+	MikeyPayloadKeyData *keyData =
+		dynamic_cast<MikeyPayloadKeyData*>(subPayloads->extractPayload( MIKEYPAYLOAD_KEYDATA_PAYLOAD_TYPE ));
+
+	int tgkLength = keyData->keyDataLength();
+	byte_t * tgk = keyData->keyData();
+
+	ka->setTgk( tgk, tgkLength );
+	ka->setKeyValidity( keyData->kv() );
+#undef kemac
+
+	if( error ){
+		byte_t authKey[20];
+		unsigned int authKeyLength = 20;
+
+		ka->genTranspAuthKey( authKey, 20 );
+		
+		errorMessage->addVPayload( MIKEY_MAC_HMAC_SHA1_160, 
+				t_received, authKey, authKeyLength  );
+
+		throw MikeyExceptionMessageContent( errorMessage );
+	}
+	addPolicyTo_ka(ka); //Is in MikeyMessage.cxx
+
+	return NULL;
+}
+
+bool MikeyMessageRSAR::authenticate(KeyAgreement* kaBase){
+	KeyAgreementRSAR* ka = dynamic_cast<KeyAgreementRSAR*>(kaBase);
+
+	if( !ka ){
+		throw MikeyExceptionMessageContent( 
+				"Not a RSAR keyagreement" );
+	}
+	
+	MikeyPayload * payload = *(lastPayload());
+	list<MikeyPayload *>::iterator payload_i;
+ 
+	if( ka->rand() == NULL ){
+		
+		MikeyPayloadRAND * randPayload;
+		
+		randPayload = (MikeyPayloadRAND*) extractPayload(MIKEYPAYLOAD_RAND_PAYLOAD_TYPE );
+		
+		if( randPayload == NULL ){
+			ka->setAuthError(
+				"The MIKEY init has no"
+				"RAND payload."
+			);
+			
+			return true;
+		}
+
+		ka->setRand( randPayload->randData(), 
+			     randPayload->randLength() );
+	}
+
+	if( isInitiatorMessage() || isResponderMessage() ){
+		if( payload->payloadType() != MIKEYPAYLOAD_SIGN_PAYLOAD_TYPE){
+			throw MikeyException( 
+			   "RSAR init did not end with a SIGN payload" );
+		}
+
+		if( isResponderMessage() &&
+		    ka->csbId() != csbId() ){
+			ka->setAuthError( "CSBID mismatch\n" );
+			return true;
+		}
+
+		// Fetch peer certificate chain
+		MRef<certificate_chain *> peerChain = ka->peerCertificateChain();
+		if( peerChain.isNull() || peerChain->get_first().isNull() ){
+			peerChain = extractCertificateChain();
+
+			if( peerChain.isNull() ){
+				ka->setAuthError( "No certificate was found" );
+				return true;
+			}
+
+			ka->setPeerCertificateChain( peerChain );
+		}
+
+ 		if( !verifySignature( peerChain->get_first() ) ){
+			cout << "Verification of the RSAR init message SIGN payload failed!"  << endl;
+			cout << "Keypair of the initiator probably mismatch!" << endl;
+			return true;
+		}
+
+		ka->setCsbId( csbId() );
+
+		if( isResponderMessage() ){
+			if( !extractPkeEnvKey( ka ) ){
+				throw MikeyException( "Decryption of envelope key failed" );
+			}
+
+			if( !verifyKemac( ka, true ) ){
+				return true;
+			}
+		}
+
+		return false;
+	}
+	else{
+		throw MikeyException( "Invalide type for a RSAR message" );
+	}
+
+}
+
+bool MikeyMessageRSAR::isInitiatorMessage() const{
+	return type() == MIKEY_TYPE_RSA_R_INIT;
+}
+
+bool MikeyMessageRSAR::isResponderMessage() const{
+	return type() == MIKEY_TYPE_RSA_R_RESP;
+}
+
+int32_t MikeyMessageRSAR::keyAgreementType() const{
+	return KEY_AGREEMENT_TYPE_RSA_R;
+}
+

Copied: trunk/libmikey/mikey/MikeyMessageRSAR.h (from rev 3088, trunk/libmikey/mikey/MikeyMessagePKE.h)
===================================================================
--- trunk/libmikey/mikey/MikeyMessagePKE.h	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/mikey/MikeyMessageRSAR.h	2007-01-04 21:37:21 UTC (rev 3089)
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien, Joachim Orrblad
+  Copyright (C) 2006 Mikael Magnusson
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ *          Johan Bilien <jobi at via.ecp.fr>
+ *	    Joachim Orrblad <joachim at orrblad.com>
+ *          Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+#ifndef MIKEYMESSAGERSAR_H
+#define MIKEYMESSAGERSAR_H
+
+#include<libmikey/libmikey_config.h>
+#include<libmikey/MikeyMessage.h>
+#include<libmikey/KeyAgreementRSAR.h>
+#include<libmcrypto/cert.h>
+
+class LIBMIKEY_API MikeyMessageRSAR: public MikeyMessage{
+	public:
+		MikeyMessageRSAR();
+		MikeyMessageRSAR( KeyAgreementRSAR* ka );
+
+		MikeyMessage * parseResponse( KeyAgreement  * ka );
+		void setOffer( KeyAgreement * ka );
+		MikeyMessage * buildResponse( KeyAgreement * ka );
+		bool authenticate( KeyAgreement  * ka );
+
+		bool isInitiatorMessage() const;
+		bool isResponderMessage() const;
+		int32_t keyAgreementType() const;
+};
+
+#endif

Modified: trunk/libmikey/mikey/MikeyPayloadHDR.cxx
===================================================================
--- trunk/libmikey/mikey/MikeyPayloadHDR.cxx	2007-01-04 19:05:51 UTC (rev 3088)
+++ trunk/libmikey/mikey/MikeyPayloadHDR.cxx	2007-01-04 21:37:21 UTC (rev 3089)
@@ -151,16 +151,16 @@
 			ret=ret+"<D-H resp>";
 			break;
 		case HDR_DATA_TYPE_DHHMAC_INIT:
-			ret=ret+"<D-H init>";
+			ret=ret+"<DHMAC init>";
 			break;
 		case HDR_DATA_TYPE_DHHMAC_RESP:
-			ret=ret+"<D-H resp>";
+			ret=ret+"<DHMAC resp>";
 			break;
 		case HDR_DATA_TYPE_RSA_R_INIT:
-			ret=ret+"<RSA-R init>";
+			ret=ret+"<RSA-R I_MSG>";
 			break;
 		case HDR_DATA_TYPE_RSA_R_RESP:
-			ret=ret+"<RSA-R resp>";
+			ret=ret+"<RSA-R R_MSG>";
 			break;
 		case HDR_DATA_TYPE_ERROR:
 			ret=ret+"<Error>";



More information about the Minisip-devel mailing list