LCOV - code coverage report
Current view: directory - security/manager/ssl/src - nsNSSASN1Object.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 199 0 0.0 %
Date: 2012-06-02 Functions: 40 0 0.0 %

       1                 : /* ***** BEGIN LICENSE BLOCK *****
       2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       3                 :  *
       4                 :  * The contents of this file are subject to the Mozilla Public License Version
       5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       6                 :  * the License. You may obtain a copy of the License at
       7                 :  * http://www.mozilla.org/MPL/
       8                 :  *
       9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      11                 :  * for the specific language governing rights and limitations under the
      12                 :  * License.
      13                 :  *
      14                 :  * The Original Code is the Netscape security libraries.
      15                 :  *
      16                 :  * The Initial Developer of the Original Code is
      17                 :  * Netscape Communications Corporation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 1994-2000
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Javier Delgadillo <javi@netscape.com>
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : #include "nsNSSASN1Object.h"
      38                 : #include "nsIComponentManager.h"
      39                 : #include "secasn1.h"
      40                 : #include "nsReadableUtils.h"
      41                 : #include "nsIMutableArray.h"
      42                 : #include "nsArrayUtils.h"
      43                 : #include "nsXPCOMCID.h"
      44                 : 
      45               0 : NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSASN1Sequence, nsIASN1Sequence, 
      46                 :                                                  nsIASN1Object)
      47               0 : NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSASN1PrintableItem, nsIASN1PrintableItem,
      48                 :                                                       nsIASN1Object)
      49                 : 
      50                 : // This function is used to interpret an integer that
      51                 : // was encoded in a DER buffer. This function is used
      52                 : // when converting a DER buffer into a nsIASN1Object 
      53                 : // structure.  This interprets the buffer in data
      54                 : // as defined by the DER (Distinguised Encoding Rules) of
      55                 : // ASN1.
      56                 : static int
      57               0 : getInteger256(unsigned char *data, unsigned int nb)
      58                 : {
      59                 :     int val;
      60                 : 
      61               0 :     switch (nb) {
      62                 :       case 1:
      63               0 :         val = data[0];
      64               0 :         break;
      65                 :       case 2:
      66               0 :         val = (data[0] << 8) | data[1];
      67               0 :         break;
      68                 :       case 3:
      69               0 :         val = (data[0] << 16) | (data[1] << 8) | data[2];
      70               0 :         break;
      71                 :       case 4:
      72               0 :         val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
      73               0 :         break;
      74                 :       default:
      75               0 :         return -1;
      76                 :     }
      77                 : 
      78               0 :     return val;
      79                 : }
      80                 : 
      81                 : // This function is used to retrieve the lenght of a DER encoded
      82                 : // item.  It looks to see if this a multibyte length and then
      83                 : // interprets the buffer accordingly to get the actual length value.
      84                 : // This funciton is used mostly while parsing the DER headers.
      85                 : // 
      86                 : // A DER encoded item has the following structure:
      87                 : //
      88                 : //  <tag><length<data consisting of lenght bytes>
      89                 : static PRInt32
      90               0 : getDERItemLength(unsigned char *data, unsigned char *end,
      91                 :                  unsigned long *bytesUsed, bool *indefinite)
      92                 : {
      93               0 :   unsigned char lbyte = *data++;
      94               0 :   PRInt32 length = -1;
      95                 :   
      96               0 :   *indefinite = false;
      97               0 :   if (lbyte >= 0x80) {
      98                 :     // Multibyte length
      99               0 :     unsigned nb = (unsigned) (lbyte & 0x7f);
     100               0 :     if (nb > 4) {
     101               0 :       return -1;
     102                 :     }
     103               0 :     if (nb > 0) {
     104                 :     
     105               0 :       if ((data+nb) > end) {
     106               0 :         return -1;
     107                 :       }
     108               0 :       length = getInteger256(data, nb);
     109               0 :       if (length < 0)
     110               0 :         return -1;
     111                 :     } else {
     112               0 :       *indefinite = true;
     113               0 :       length = 0;
     114                 :     }
     115               0 :     *bytesUsed = nb+1;
     116                 :   } else {
     117               0 :     length = lbyte;
     118               0 :     *bytesUsed = 1; 
     119                 :   }
     120               0 :   return length;
     121                 : }
     122                 : 
     123                 : static nsresult
     124               0 : buildASN1ObjectFromDER(unsigned char *data,
     125                 :                        unsigned char *end,
     126                 :                        nsIASN1Sequence *parent)
     127                 : {
     128                 :   nsresult rv;
     129               0 :   nsCOMPtr<nsIASN1Sequence> sequence;
     130               0 :   nsCOMPtr<nsIASN1PrintableItem> printableItem;
     131               0 :   nsCOMPtr<nsIASN1Object> asn1Obj;
     132               0 :   nsCOMPtr<nsIMutableArray> parentObjects;
     133                 : 
     134               0 :   NS_ENSURE_ARG_POINTER(parent);
     135               0 :   if (data >= end)
     136               0 :     return NS_OK;
     137                 : 
     138                 :   unsigned char code, tagnum;
     139                 : 
     140                 :   // A DER item has the form of |tag|len|data
     141                 :   // tag is one byte and describes the type of elment
     142                 :   //     we are dealing with.
     143                 :   // len is a DER encoded int telling us how long the data is
     144                 :   // data is a buffer that is len bytes long and has to be
     145                 :   //      interpreted according to its type.
     146                 :   unsigned long bytesUsed;
     147                 :   bool indefinite;
     148                 :   PRInt32 len;
     149                 :   PRUint32 type;
     150                 : 
     151               0 :   rv = parent->GetASN1Objects(getter_AddRefs(parentObjects));
     152               0 :   if (NS_FAILED(rv) || parentObjects == nsnull)
     153               0 :     return NS_ERROR_FAILURE;
     154               0 :   while (data < end) {
     155               0 :     code = *data;
     156               0 :     tagnum = code & SEC_ASN1_TAGNUM_MASK;
     157                 : 
     158                 :     /*
     159                 :      * NOTE: This code does not (yet) handle the high-tag-number form!
     160                 :      */
     161               0 :     if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
     162               0 :       return NS_ERROR_FAILURE;
     163                 :     }
     164               0 :     data++;
     165               0 :     len = getDERItemLength(data, end, &bytesUsed, &indefinite);
     166               0 :     data += bytesUsed;
     167               0 :     if ((len < 0) || ((data+len) > end))
     168               0 :       return NS_ERROR_FAILURE;
     169                 : 
     170               0 :     if (code & SEC_ASN1_CONSTRUCTED) {
     171               0 :       if (len > 0 || indefinite) {
     172               0 :         sequence = new nsNSSASN1Sequence();
     173               0 :         switch (code & SEC_ASN1_CLASS_MASK) {
     174                 :         case SEC_ASN1_UNIVERSAL:
     175               0 :           type = tagnum;
     176               0 :           break;
     177                 :         case SEC_ASN1_APPLICATION:
     178               0 :           type = nsIASN1Object::ASN1_APPLICATION;
     179               0 :           break;
     180                 :         case SEC_ASN1_CONTEXT_SPECIFIC:
     181               0 :           type = nsIASN1Object::ASN1_CONTEXT_SPECIFIC;
     182               0 :           break;
     183                 :         case SEC_ASN1_PRIVATE:
     184               0 :           type = nsIASN1Object::ASN1_PRIVATE;
     185               0 :           break;
     186                 :         default:
     187               0 :           NS_ERROR("Bad DER");
     188               0 :           return NS_ERROR_FAILURE;
     189                 :         }
     190               0 :         sequence->SetTag(tagnum);
     191               0 :         sequence->SetType(type);
     192               0 :         rv = buildASN1ObjectFromDER(data, (len == 0) ? end : data + len, 
     193               0 :                                     sequence);
     194               0 :         asn1Obj = sequence;
     195                 :       }
     196                 :     } else {
     197               0 :       printableItem = new nsNSSASN1PrintableItem();
     198                 : 
     199               0 :       asn1Obj = printableItem;
     200               0 :       asn1Obj->SetType(tagnum);
     201               0 :       asn1Obj->SetTag(tagnum); 
     202               0 :       printableItem->SetData((char*)data, len);
     203                 :     }
     204               0 :     data += len;
     205               0 :     parentObjects->AppendElement(asn1Obj, false);
     206                 :   }
     207                 : 
     208               0 :   return NS_OK;
     209                 : }
     210                 : 
     211                 : nsresult
     212               0 : CreateFromDER(unsigned char *data,
     213                 :               unsigned int   len,
     214                 :               nsIASN1Object **retval)
     215                 : {
     216               0 :   nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence;
     217               0 :   *retval = nsnull;
     218                 :   
     219               0 :   nsresult rv =  buildASN1ObjectFromDER(data, data+len, sequence);
     220                 : 
     221               0 :   if (NS_SUCCEEDED(rv)) {
     222                 :     // The actual object will be the first element inserted
     223                 :     // into the sequence of the sequence variable we created.
     224               0 :     nsCOMPtr<nsIMutableArray> elements;
     225                 : 
     226               0 :     sequence->GetASN1Objects(getter_AddRefs(elements));
     227               0 :     nsCOMPtr<nsIASN1Object> asn1Obj = do_QueryElementAt(elements, 0);
     228               0 :     *retval = asn1Obj;
     229               0 :     if (*retval == nsnull)
     230               0 :       return NS_ERROR_FAILURE;
     231                 : 
     232               0 :     NS_ADDREF(*retval);
     233                 :       
     234                 :   }
     235               0 :   return rv; 
     236                 : }
     237                 : 
     238               0 : nsNSSASN1Sequence::nsNSSASN1Sequence() : mType(0),
     239                 :                                          mTag(0),
     240                 :                                          mIsValidContainer(true),
     241               0 :                                          mIsExpanded(true)
     242                 : {
     243                 :   /* member initializers and constructor code */
     244               0 : }
     245                 : 
     246               0 : nsNSSASN1Sequence::~nsNSSASN1Sequence()
     247                 : {
     248                 :   /* destructor code */
     249               0 : }
     250                 : 
     251                 : NS_IMETHODIMP 
     252               0 : nsNSSASN1Sequence::GetASN1Objects(nsIMutableArray * *aASN1Objects)
     253                 : {
     254               0 :   if (mASN1Objects == nsnull) {
     255               0 :     mASN1Objects = do_CreateInstance(NS_ARRAY_CONTRACTID);
     256                 :   }
     257               0 :   *aASN1Objects = mASN1Objects;
     258               0 :   NS_IF_ADDREF(*aASN1Objects);
     259               0 :   return NS_OK;
     260                 : }
     261                 : 
     262                 : NS_IMETHODIMP 
     263               0 : nsNSSASN1Sequence::SetASN1Objects(nsIMutableArray * aASN1Objects)
     264                 : {
     265               0 :   mASN1Objects = aASN1Objects;
     266               0 :   return NS_OK;
     267                 : }
     268                 : 
     269                 : NS_IMETHODIMP 
     270               0 : nsNSSASN1Sequence::GetTag(PRUint32 *aTag)
     271                 : {
     272               0 :   *aTag = mTag;
     273               0 :   return NS_OK;
     274                 : }
     275                 : 
     276                 : NS_IMETHODIMP 
     277               0 : nsNSSASN1Sequence::SetTag(PRUint32 aTag)
     278                 : {
     279               0 :   mTag = aTag;
     280               0 :   return NS_OK;
     281                 : }
     282                 : 
     283                 : NS_IMETHODIMP 
     284               0 : nsNSSASN1Sequence::GetType(PRUint32 *aType)
     285                 : {
     286               0 :   *aType = mType;
     287               0 :   return NS_OK;
     288                 : }
     289                 : 
     290                 : NS_IMETHODIMP 
     291               0 : nsNSSASN1Sequence::SetType(PRUint32 aType)
     292                 : {
     293               0 :   mType = aType;
     294               0 :   return NS_OK;
     295                 : }
     296                 : 
     297                 : NS_IMETHODIMP 
     298               0 : nsNSSASN1Sequence::GetDisplayName(nsAString &aDisplayName)
     299                 : {
     300               0 :   aDisplayName = mDisplayName;
     301               0 :   return NS_OK;
     302                 : }
     303                 : 
     304                 : NS_IMETHODIMP 
     305               0 : nsNSSASN1Sequence::SetDisplayName(const nsAString &aDisplayName)
     306                 : {
     307               0 :   mDisplayName = aDisplayName;
     308               0 :   return NS_OK;
     309                 : }
     310                 : 
     311                 : NS_IMETHODIMP 
     312               0 : nsNSSASN1Sequence::GetDisplayValue(nsAString &aDisplayValue)
     313                 : {
     314               0 :   aDisplayValue = mDisplayValue;
     315               0 :   return NS_OK;
     316                 : }
     317                 : 
     318                 : NS_IMETHODIMP 
     319               0 : nsNSSASN1Sequence::SetDisplayValue(const nsAString &aDisplayValue)
     320                 : {
     321               0 :   mDisplayValue = aDisplayValue;
     322               0 :   return NS_OK;
     323                 : }
     324                 : 
     325                 : NS_IMETHODIMP 
     326               0 : nsNSSASN1Sequence::GetIsValidContainer(bool *aIsValidContainer)
     327                 : {
     328               0 :   NS_ENSURE_ARG_POINTER(aIsValidContainer);
     329               0 :   *aIsValidContainer = mIsValidContainer;
     330               0 :   return NS_OK;
     331                 : }
     332                 : 
     333                 : NS_IMETHODIMP
     334               0 : nsNSSASN1Sequence::SetIsValidContainer(bool aIsValidContainer)
     335                 : {
     336               0 :   mIsValidContainer = aIsValidContainer;
     337               0 :   SetIsExpanded(mIsValidContainer);
     338               0 :   return NS_OK;
     339                 : }
     340                 : 
     341                 : NS_IMETHODIMP 
     342               0 : nsNSSASN1Sequence::GetIsExpanded(bool *aIsExpanded)
     343                 : {
     344               0 :   NS_ENSURE_ARG_POINTER(aIsExpanded);
     345               0 :   *aIsExpanded = mIsExpanded;
     346               0 :   return NS_OK;
     347                 : }
     348                 : 
     349                 : NS_IMETHODIMP 
     350               0 : nsNSSASN1Sequence::SetIsExpanded(bool aIsExpanded)
     351                 : {
     352               0 :   mIsExpanded = aIsExpanded;
     353               0 :   return NS_OK;
     354                 : }
     355                 : 
     356                 : 
     357               0 : nsNSSASN1PrintableItem::nsNSSASN1PrintableItem() : mType(0),
     358                 :                                                    mTag(0),
     359                 :                                                    mData(nsnull),
     360               0 :                                                    mLen(0)
     361                 : {
     362                 :   /* member initializers and constructor code */
     363               0 : }
     364                 : 
     365               0 : nsNSSASN1PrintableItem::~nsNSSASN1PrintableItem()
     366                 : {
     367                 :   /* destructor code */
     368               0 :   if (mData)
     369               0 :     nsMemory::Free(mData);
     370               0 : }
     371                 : 
     372                 : /* readonly attribute wstring value; */
     373                 : NS_IMETHODIMP 
     374               0 : nsNSSASN1PrintableItem::GetDisplayValue(nsAString &aValue)
     375                 : {
     376               0 :   aValue = mValue;
     377               0 :   return NS_OK;
     378                 : }
     379                 : 
     380                 : NS_IMETHODIMP 
     381               0 : nsNSSASN1PrintableItem::SetDisplayValue(const nsAString &aValue)
     382                 : {
     383               0 :   mValue = aValue;
     384               0 :   return NS_OK;
     385                 : }
     386                 : 
     387                 : NS_IMETHODIMP 
     388               0 : nsNSSASN1PrintableItem::GetTag(PRUint32 *aTag)
     389                 : {
     390               0 :   *aTag = mTag;
     391               0 :   return NS_OK;
     392                 : }
     393                 : 
     394                 : NS_IMETHODIMP 
     395               0 : nsNSSASN1PrintableItem::SetTag(PRUint32 aTag)
     396                 : {
     397               0 :   mTag = aTag;
     398               0 :   return NS_OK;
     399                 : }
     400                 : 
     401                 : NS_IMETHODIMP 
     402               0 : nsNSSASN1PrintableItem::GetType(PRUint32 *aType)
     403                 : {
     404               0 :   *aType = mType;
     405               0 :   return NS_OK;
     406                 : }
     407                 : 
     408                 : NS_IMETHODIMP 
     409               0 : nsNSSASN1PrintableItem::SetType(PRUint32 aType)
     410                 : {
     411               0 :   mType = aType;
     412               0 :   return NS_OK;
     413                 : }
     414                 : 
     415                 : NS_IMETHODIMP 
     416               0 : nsNSSASN1PrintableItem::SetData(char *data, PRUint32 len)
     417                 : {
     418               0 :   if (len > 0) {
     419               0 :     if (mLen < len) {
     420               0 :       unsigned char* newData = (unsigned char*)nsMemory::Realloc(mData, len);
     421               0 :       if (!newData)
     422               0 :         return NS_ERROR_OUT_OF_MEMORY;
     423                 : 
     424               0 :       mData = newData;
     425                 :     }
     426                 : 
     427               0 :     memcpy(mData, data, len);
     428               0 :   } else if (len == 0) {
     429               0 :     if (mData) {
     430               0 :       nsMemory::Free(mData);
     431               0 :       mData = nsnull;
     432                 :     }
     433                 :   }
     434               0 :   mLen = len;
     435               0 :   return NS_OK;  
     436                 : }
     437                 : 
     438                 : NS_IMETHODIMP
     439               0 : nsNSSASN1PrintableItem::GetData(char **outData, PRUint32 *outLen)
     440                 : {
     441               0 :   NS_ENSURE_ARG_POINTER(outData);
     442               0 :   NS_ENSURE_ARG_POINTER(outLen);
     443                 : 
     444               0 :   *outData = (char*)mData;
     445               0 :   *outLen  = mLen;
     446               0 :   return NS_OK;
     447                 : }
     448                 : 
     449                 : /* attribute wstring displayName; */
     450                 : NS_IMETHODIMP 
     451               0 : nsNSSASN1PrintableItem::GetDisplayName(nsAString &aDisplayName)
     452                 : {
     453               0 :   aDisplayName = mDisplayName;
     454               0 :   return NS_OK;
     455                 : }
     456                 : 
     457                 : NS_IMETHODIMP 
     458               0 : nsNSSASN1PrintableItem::SetDisplayName(const nsAString &aDisplayName)
     459                 : {
     460               0 :   mDisplayName = aDisplayName;
     461               0 :   return NS_OK;
     462                 : }
     463                 : 

Generated by: LCOV version 1.7