LCOV - code coverage report
Current view: top level - security/manager/ssl - nsNSSASN1Object.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 200 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13