natfw/natfwunsaf_protocols/unsaf_codec/src/natfwunsafmessage.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include <es_sock.h>
       
    22 #include "natfwunsafmessage.h"
       
    23 #include "natfwunsaftransactionid.h"
       
    24 #include "natfwunsafmessageintegrityattribute.h"
       
    25 #include "natfwunsaffingerprintattribute.h"
       
    26 #include "natfwunsafutils.h"
       
    27 
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // CNATFWUNSAFMessage::CNATFWUNSAFMessage
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 CNATFWUNSAFMessage::CNATFWUNSAFMessage(
       
    34     const TNATFWUNSAFTransactionID& aTransactionID)
       
    35 #ifdef TEST_EUNIT
       
    36     : iAttributes(1)
       
    37 #endif
       
    38     {
       
    39     iTransactionID = aTransactionID;
       
    40     }
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CNATFWUNSAFMessage::~CNATFWUNSAFMessage
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 CNATFWUNSAFMessage::~CNATFWUNSAFMessage()
       
    47     {
       
    48     iAttributes.ResetAndDestroy();
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CNATFWUNSAFMessage::TransactionID
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 EXPORT_C TNATFWUNSAFTransactionID CNATFWUNSAFMessage::TransactionID() const
       
    56     {
       
    57     return iTransactionID;
       
    58     }
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // CNATFWUNSAFMessage::HasAttribute
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 EXPORT_C TBool CNATFWUNSAFMessage::HasAttribute(
       
    65     CNATFWUNSAFAttribute::TType aType) const
       
    66     {
       
    67     return Attribute(aType) ? ETrue : EFalse;
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CNATFWUNSAFMessage::Attribute
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 EXPORT_C CNATFWUNSAFAttribute* CNATFWUNSAFMessage::Attribute(
       
    75     CNATFWUNSAFAttribute::TType aType) const
       
    76     {
       
    77     for (TInt i = 0; i < iAttributes.Count(); ++i)
       
    78         {
       
    79         if (iAttributes[i]->Type() == aType)
       
    80             {
       
    81             return iAttributes[i];
       
    82             }
       
    83         }
       
    84 
       
    85     return NULL;
       
    86     }
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 // CNATFWUNSAFMessage::AddAttributeL
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 EXPORT_C void CNATFWUNSAFMessage::AddAttributeL(
       
    93     CNATFWUNSAFAttribute* aAttribute)
       
    94     {
       
    95     __ASSERT_ALWAYS(aAttribute, User::Leave(KErrArgument));
       
    96 
       
    97     iAttributes.AppendL(aAttribute);
       
    98     }
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // CNATFWUNSAFMessage::DetachAttribute
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 EXPORT_C void CNATFWUNSAFMessage::DetachAttribute(
       
   105     const CNATFWUNSAFAttribute* aAttribute)
       
   106     {
       
   107     TInt pos = iAttributes.Find(aAttribute);
       
   108     if (pos != KErrNotFound)
       
   109         {
       
   110         iAttributes.Remove(pos);
       
   111         }
       
   112     }
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // CNATFWUNSAFMessage::DeleteAttribute
       
   116 // Start search from the end of the array, so that deleting an attribute doesn't
       
   117 // affect the positions of those attributes which haven't yet been checked.
       
   118 // -----------------------------------------------------------------------------
       
   119 //
       
   120 EXPORT_C void CNATFWUNSAFMessage::DeleteAttribute(TUint16 aType)
       
   121     {
       
   122     for (TInt i = iAttributes.Count() - 1; i >= 0; --i)
       
   123         {
       
   124         if (iAttributes[i]->Type() == aType)
       
   125             {
       
   126             CNATFWUNSAFAttribute* attr = iAttributes[i];
       
   127             DetachAttribute(attr);
       
   128             delete attr;
       
   129             }
       
   130         }
       
   131     }
       
   132 
       
   133 // -----------------------------------------------------------------------------
       
   134 // CNATFWUNSAFMessage::EncodeL
       
   135 // -----------------------------------------------------------------------------
       
   136 //
       
   137 EXPORT_C CBufBase* CNATFWUNSAFMessage::EncodeL() const
       
   138     {
       
   139     CBufBase* msg = EncodeMessageHeaderLC();
       
   140 
       
   141     for (TInt i = 0; i < iAttributes.Count(); ++i)
       
   142         {
       
   143         if (iAttributes[i]->Type() != CNATFWUNSAFAttribute::EMessageIntegrity &&
       
   144             iAttributes[i]->Type() != CNATFWUNSAFAttribute::EFingerprint)
       
   145             {
       
   146             HBufC8* attribute = iAttributes[i]->EncodeL();
       
   147             CleanupStack::PushL(attribute);
       
   148             msg->InsertL(msg->Size(), *attribute);
       
   149             CleanupStack::PopAndDestroy(attribute);
       
   150             }
       
   151         }
       
   152     CleanupStack::Pop(msg);
       
   153     msg->Compress();
       
   154     SetMessageLength(*msg);
       
   155 
       
   156     return msg;
       
   157     }
       
   158 
       
   159 // -----------------------------------------------------------------------------
       
   160 // CNATFWUNSAFMessage::EncodeL
       
   161 // 1. Encode the UNSAF message normally.
       
   162 // 2. Create a MESSAGE-INTEGRITY attribute. This updates also the header's
       
   163 //    length field to include the MESSAGE-INTEGRITY before computing the hash.
       
   164 // 3. Encode it to the last attribute of the UNSAF message.
       
   165 // 4. Create a FINGERPRINT attribute. This updates also the header's
       
   166 //    length field to include the FINGERPRINT before computing the hash.
       
   167 // 5. Encode it to the last attribute of the UNSAF message.
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 EXPORT_C CBufBase* CNATFWUNSAFMessage::EncodeL(
       
   171     const TDesC8& aSharedSecret,
       
   172     TBool aUseFingerprint) const
       
   173     {
       
   174     CBufBase* msg = EncodeL();
       
   175     CleanupStack::PushL(msg);
       
   176     if ( aSharedSecret.Length() )
       
   177         {
       
   178         //Long term credentials need be used if there's a REALM attribute
       
   179         CNATFWUNSAFMessageIntegrityAttribute* msgIntegrity =
       
   180             CNATFWUNSAFMessageIntegrityAttribute::NewLC(aSharedSecret, *msg,
       
   181                 HasAttribute( CNATFWUNSAFAttribute::ERealm ));
       
   182 
       
   183         HBufC8* encodedMsgIntegrity = msgIntegrity->EncodeL();
       
   184         CleanupStack::PushL(encodedMsgIntegrity);
       
   185         msg->InsertL(msg->Size(), *encodedMsgIntegrity);
       
   186         CleanupStack::PopAndDestroy(encodedMsgIntegrity);
       
   187         CleanupStack::PopAndDestroy(msgIntegrity);
       
   188         }
       
   189     if ( aUseFingerprint )
       
   190         {
       
   191         CNATFWUNSAFFingerprintAttribute* fingerprint =
       
   192             CNATFWUNSAFFingerprintAttribute::NewLC(*msg);
       
   193 
       
   194         HBufC8* encodedFingerprint = fingerprint->EncodeL();
       
   195         CleanupStack::PushL(encodedFingerprint);
       
   196         msg->InsertL(msg->Size(), *encodedFingerprint);
       
   197         CleanupStack::PopAndDestroy(encodedFingerprint);
       
   198         CleanupStack::PopAndDestroy(fingerprint); 
       
   199         }
       
   200 
       
   201     CleanupStack::Pop(msg);
       
   202     msg->Compress();
       
   203 
       
   204     return msg;
       
   205     }
       
   206 
       
   207 // -----------------------------------------------------------------------------
       
   208 // CNATFWUNSAFMessage::UnknownMandatoryAttributeFound
       
   209 // -----------------------------------------------------------------------------
       
   210 //
       
   211 void CNATFWUNSAFMessage::UnknownMandatoryAttributeFound()
       
   212     {
       
   213     iUnknownMandatoryAttributes = ETrue;
       
   214     }
       
   215 
       
   216 // -----------------------------------------------------------------------------
       
   217 // CNATFWUNSAFMessage::HasUnknownMandatoryAttributes
       
   218 // -----------------------------------------------------------------------------
       
   219 //
       
   220 EXPORT_C TBool CNATFWUNSAFMessage::HasUnknownMandatoryAttributes() const
       
   221     {
       
   222     return iUnknownMandatoryAttributes;
       
   223     }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // CNATFWUNSAFMessage::EncodeMessageHeaderLC
       
   227 // -----------------------------------------------------------------------------
       
   228 //
       
   229 CBufBase* CNATFWUNSAFMessage::EncodeMessageHeaderLC() const
       
   230     {
       
   231     CBufBase* header = CBufFlat::NewL(EHeaderSize);
       
   232     CleanupStack::PushL(header);
       
   233 
       
   234     TUint16 messageType = Type();
       
   235     TUint16 bigEndianType(0);
       
   236     BigEndian::Put16(reinterpret_cast<TUint8*>(&bigEndianType), messageType);
       
   237     //First two bits of a STUN message are zero
       
   238     bigEndianType = bigEndianType & EMessageTypeMask;
       
   239     header->InsertL(EMessageTypeOffset, &bigEndianType, sizeof(bigEndianType));
       
   240 
       
   241 
       
   242     TUint16 msgLength = 0;
       
   243     //Value is zero, so it is same also in the big endian representation
       
   244     header->InsertL(EMessageLengthOffset, &msgLength, sizeof(msgLength));
       
   245 
       
   246     TUint32 bigEndianCookie(0);
       
   247     BigEndian::Put32(reinterpret_cast<TUint8*>(&bigEndianCookie), EMagicCookie);
       
   248     header->InsertL(EMagicCookieOffset,
       
   249                     &bigEndianCookie,
       
   250                     sizeof(bigEndianCookie));
       
   251 
       
   252     header->InsertL(ETransactionIDOffset,
       
   253                     iTransactionID,
       
   254                     KMaxNATFWUNSAFTransactionIdLength);
       
   255     return header;
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CNATFWUNSAFMessage::MessageLength
       
   260 // TInt is guaranteed to be at least 32 bits.
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 TInt CNATFWUNSAFMessage::MessageLength(const TDesC8& aNATFWUNSAFMessage)
       
   264     {
       
   265     if (aNATFWUNSAFMessage.Length() < EHeaderSize)
       
   266         {
       
   267         return KErrNotFound;
       
   268         }
       
   269 
       
   270     return BigEndian::Get16(aNATFWUNSAFMessage.Mid(EMessageLengthOffset).Ptr());
       
   271     }
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // CNATFWUNSAFMessage::SetMessageLength
       
   275 // UNSAF message length does not include the NATFWUNSAF header
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 void CNATFWUNSAFMessage::SetMessageLength(CBufBase& aNATFWUNSAFMessage)
       
   279     {
       
   280     SetMessageLength(aNATFWUNSAFMessage,
       
   281         aNATFWUNSAFMessage.Size() - EHeaderSize);
       
   282     }
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // CNATFWUNSAFMessage::SetMessageLength
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 void CNATFWUNSAFMessage::SetMessageLength(CBufBase& aNATFWUNSAFMessage,
       
   289     TInt aLength)
       
   290     {
       
   291     __ASSERT_ALWAYS(aLength >= 0, User::Panic(KNullDesC, KErrUnderflow));
       
   292 
       
   293     TUint16 bigEndianLength(0);
       
   294     BigEndian::Put16(reinterpret_cast<TUint8*>(&bigEndianLength),
       
   295                      static_cast<TUint16>(aLength));
       
   296 
       
   297     aNATFWUNSAFMessage.Write(EMessageLengthOffset,
       
   298                         &bigEndianLength,
       
   299                         sizeof(bigEndianLength));
       
   300     }