Back to index

lightning-sunbird  0.9+nobinonly
Functions | Variables
nsNSSASN1Object.cpp File Reference
#include "nsNSSASN1Object.h"
#include "nsIComponentManager.h"
#include "secasn1.h"
#include "nsReadableUtils.h"
#include "nsArray.h"
#include "nsXPCOMCID.h"

Go to the source code of this file.

Functions

 NS_IMPL_THREADSAFE_ISUPPORTS2 (nsNSSASN1Sequence, nsIASN1Sequence, nsIASN1Object) NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSASN1PrintableItem
static nsIASN1Object int getInteger256 (unsigned char *data, unsigned int nb)
static PRInt32 getDERItemLength (unsigned char *data, unsigned char *end, unsigned long *bytesUsed, PRBool *indefinite)
static nsresult buildASN1ObjectFromDER (unsigned char *data, unsigned char *end, nsIASN1Sequence *parent)
nsresult CreateFromDER (unsigned char *data, unsigned int len, nsIASN1Object **retval)

Variables

 nsIASN1PrintableItem

Function Documentation

static nsresult buildASN1ObjectFromDER ( unsigned char *  data,
unsigned char *  end,
nsIASN1Sequence parent 
) [static]

Definition at line 123 of file nsNSSASN1Object.cpp.

{
  nsresult rv;
  nsCOMPtr<nsIASN1Sequence> sequence;
  nsCOMPtr<nsIASN1PrintableItem> printableItem;
  nsCOMPtr<nsIASN1Object> asn1Obj;
  nsCOMPtr<nsIMutableArray> parentObjects;

  NS_ENSURE_ARG_POINTER(parent);
  if (data >= end)
    return NS_OK;

  unsigned char code, tagnum;

  // A DER item has the form of |tag|len|data
  // tag is one byte and describes the type of elment
  //     we are dealing with.
  // len is a DER encoded int telling us how long the data is
  // data is a buffer that is len bytes long and has to be
  //      interpreted according to its type.
  unsigned long bytesUsed;
  PRBool indefinite;
  PRInt32 len;
  PRUint32 type;

  if (parent == nsnull) {
    parent = new nsNSSASN1Sequence();
    NS_IF_ADDREF(parent);
  }
  if (parent == nsnull) 
    return NS_ERROR_FAILURE;

  rv = parent->GetASN1Objects(getter_AddRefs(parentObjects));
  if (NS_FAILED(rv) || parentObjects == nsnull)
    return NS_ERROR_FAILURE;
  while (data < end) {
    code = *data;
    tagnum = code & SEC_ASN1_TAGNUM_MASK;

    /*
     * NOTE: This code does not (yet) handle the high-tag-number form!
     */
    if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
      return NS_ERROR_FAILURE;
    }
    data++;
    len = getDERItemLength(data, end, &bytesUsed, &indefinite);
    data += bytesUsed;
    if ((len < 0) || ((data+len) > end))
      return NS_ERROR_FAILURE;

    if (code & SEC_ASN1_CONSTRUCTED) {
      if (len > 0 || indefinite) {
        sequence = new nsNSSASN1Sequence();
        switch (code & SEC_ASN1_CLASS_MASK) {
        case SEC_ASN1_UNIVERSAL:
          type = tagnum;
          break;
        case SEC_ASN1_APPLICATION:
          type = nsIASN1Object::ASN1_APPLICATION;
          break;
        case SEC_ASN1_CONTEXT_SPECIFIC:
          type = nsIASN1Object::ASN1_CONTEXT_SPECIFIC;
          break;
        case SEC_ASN1_PRIVATE:
          type = nsIASN1Object::ASN1_PRIVATE;
          break;
        default:
          NS_ASSERTION(0,"Bad DER");
          return NS_ERROR_FAILURE;
        }
        sequence->SetTag(tagnum);
        sequence->SetType(type);
        rv = buildASN1ObjectFromDER(data, (len == 0) ? end : data + len, 
                                    sequence);
        asn1Obj = sequence;
      }
    } else {
      printableItem = new nsNSSASN1PrintableItem();

      asn1Obj = printableItem;
      asn1Obj->SetType(tagnum);
      asn1Obj->SetTag(tagnum); 
      printableItem->SetData((char*)data, len);
    }
    data += len;
    parentObjects->AppendElement(asn1Obj, PR_FALSE);
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult CreateFromDER ( unsigned char *  data,
unsigned int  len,
nsIASN1Object **  retval 
)

Definition at line 218 of file nsNSSASN1Object.cpp.

{
  nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence;
  *retval = nsnull;
  
  nsresult rv =  buildASN1ObjectFromDER(data, data+len, sequence);

  if (NS_SUCCEEDED(rv)) {
    // The actual object will be the first element inserted
    // into the sequence of the sequence variable we created.
    nsCOMPtr<nsIMutableArray> elements;

    sequence->GetASN1Objects(getter_AddRefs(elements));
    nsCOMPtr<nsIASN1Object> asn1Obj = do_QueryElementAt(elements, 0);
    *retval = asn1Obj;
    if (*retval == nsnull)
      return NS_ERROR_FAILURE;

    NS_ADDREF(*retval);
      
  }
  return rv; 
}

Here is the call graph for this function:

static PRInt32 getDERItemLength ( unsigned char *  data,
unsigned char *  end,
unsigned long bytesUsed,
PRBool indefinite 
) [static]

Definition at line 89 of file nsNSSASN1Object.cpp.

{
  unsigned char lbyte = *data++;
  PRInt32 length = -1;
  
  *indefinite = PR_FALSE;
  if (lbyte >= 0x80) {
    // Multibyte length
    unsigned nb = (unsigned) (lbyte & 0x7f);
    if (nb > 4) {
      return -1;
    }
    if (nb > 0) {
    
      if ((data+nb) > end) {
        return -1;
      }
      length = getInteger256(data, nb);
      if (length < 0)
        return -1;
    } else {
      *indefinite = PR_TRUE;
      length = 0;
    }
    *bytesUsed = nb+1;
  } else {
    length = lbyte;
    *bytesUsed = 1; 
  }
  return length;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsIASN1Object int getInteger256 ( unsigned char *  data,
unsigned int  nb 
) [static]

Definition at line 56 of file nsNSSASN1Object.cpp.

{
    int val;

    switch (nb) {
      case 1:
        val = data[0];
        break;
      case 2:
        val = (data[0] << 8) | data[1];
        break;
      case 3:
        val = (data[0] << 16) | (data[1] << 8) | data[2];
        break;
      case 4:
        val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
        break;
      default:
        return -1;
    }

    return val;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 46 of file nsNSSASN1Object.cpp.