diff options
Diffstat (limited to 'security/nss/lib/util/derenc.c')
-rw-r--r-- | security/nss/lib/util/derenc.c | 504 |
1 files changed, 0 insertions, 504 deletions
diff --git a/security/nss/lib/util/derenc.c b/security/nss/lib/util/derenc.c deleted file mode 100644 index 191b00528..000000000 --- a/security/nss/lib/util/derenc.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "secder.h" -#include "secerr.h" -/* - * Generic templates for individual/simple items. - */ - -DERTemplate SECAnyTemplate[] = { - { DER_ANY, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECBitStringTemplate[] = { - { DER_BIT_STRING, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECBooleanTemplate[] = { - { DER_BOOLEAN, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECIA5StringTemplate[] = { - { DER_IA5_STRING, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECIntegerTemplate[] = { - { DER_INTEGER, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECNullTemplate[] = { - { DER_NULL, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECObjectIDTemplate[] = { - { DER_OBJECT_ID, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECOctetStringTemplate[] = { - { DER_OCTET_STRING, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECPrintableStringTemplate[] = { - { DER_PRINTABLE_STRING, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECT61StringTemplate[] = { - { DER_T61_STRING, - 0, NULL, sizeof(SECItem) } -}; - -DERTemplate SECUTCTimeTemplate[] = { - { DER_UTC_TIME, - 0, NULL, sizeof(SECItem) } -}; - - -static int -header_length(DERTemplate *dtemplate, uint32 contents_len) -{ - uint32 len; - unsigned long encode_kind, under_kind; - PRBool explicit, optional, universal; - - encode_kind = dtemplate->kind; - - explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE; - optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE; - universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL) - ? PR_TRUE : PR_FALSE; - - PORT_Assert (!(explicit && universal)); /* bad templates */ - - if (encode_kind & DER_POINTER) { - if (dtemplate->sub != NULL) { - under_kind = dtemplate->sub->kind; - if (universal) { - encode_kind = under_kind; - } - } else if (universal) { - under_kind = encode_kind & ~DER_POINTER; - } else { - under_kind = dtemplate->arg; - } - } else if (encode_kind & DER_INLINE) { - under_kind = dtemplate->sub->kind; - if (universal) { - encode_kind = under_kind; - } - } else if (universal) { - under_kind = encode_kind; - } else { - under_kind = dtemplate->arg; - } - - /* This is only used in decoding; it plays no part in encoding. */ - if (under_kind & DER_DERPTR) - return 0; - - /* No header at all for an "empty" optional. */ - if ((contents_len == 0) && optional) - return 0; - - /* And no header for a full DER_ANY. */ - if (encode_kind & DER_ANY) - return 0; - - /* - * The common case: one octet for identifier and as many octets - * as necessary to hold the content length. - */ - len = 1 + DER_LengthLength(contents_len); - - /* Account for the explicit wrapper, if necessary. */ - if (explicit) { -#if 0 /* - * Well, I was trying to do something useful, but these - * assertions are too restrictive on valid templates. - * I wanted to make sure that the top-level "kind" of - * a template does not also specify DER_EXPLICIT, which - * should only modify a component field. Maybe later - * I can figure out a better way to detect such a problem, - * but for now I must remove these checks altogether. - */ - /* - * This modifier applies only to components of a set or sequence; - * it should never be used on a set/sequence itself -- confirm. - */ - PORT_Assert (under_kind != DER_SEQUENCE); - PORT_Assert (under_kind != DER_SET); -#endif - - len += 1 + DER_LengthLength(len + contents_len); - } - - return len; -} - - -static uint32 -contents_length(DERTemplate *dtemplate, void *src) -{ - uint32 len; - unsigned long encode_kind, under_kind; - PRBool universal; - - - PORT_Assert (src != NULL); - - encode_kind = dtemplate->kind; - - universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL) - ? PR_TRUE : PR_FALSE; - encode_kind &= ~DER_OPTIONAL; - - if (encode_kind & DER_POINTER) { - src = *(void **)src; - if (src == NULL) { - return 0; - } - if (dtemplate->sub != NULL) { - dtemplate = dtemplate->sub; - under_kind = dtemplate->kind; - src = (void *)((char *)src + dtemplate->offset); - } else if (universal) { - under_kind = encode_kind & ~DER_POINTER; - } else { - under_kind = dtemplate->arg; - } - } else if (encode_kind & DER_INLINE) { - PORT_Assert (dtemplate->sub != NULL); - dtemplate = dtemplate->sub; - under_kind = dtemplate->kind; - src = (void *)((char *)src + dtemplate->offset); - } else if (universal) { - under_kind = encode_kind; - } else { - under_kind = dtemplate->arg; - } - - /* Having any of these bits is not expected here... */ - PORT_Assert ((under_kind & (DER_EXPLICIT | DER_INLINE | DER_OPTIONAL - | DER_POINTER | DER_SKIP)) == 0); - - /* This is only used in decoding; it plays no part in encoding. */ - if (under_kind & DER_DERPTR) - return 0; - - if (under_kind & DER_INDEFINITE) { - uint32 sub_len; - void **indp; - - indp = *(void ***)src; - if (indp == NULL) - return 0; - - len = 0; - under_kind &= ~DER_INDEFINITE; - - if (under_kind == DER_SET || under_kind == DER_SEQUENCE) { - DERTemplate *tmpt; - void *sub_src; - - tmpt = dtemplate->sub; - - for (; *indp != NULL; indp++) { - sub_src = (void *)((char *)(*indp) + tmpt->offset); - sub_len = contents_length (tmpt, sub_src); - len += sub_len + header_length (tmpt, sub_len); - } - } else { - /* - * XXX Lisa is not sure this code (for handling, for example, - * DER_INDEFINITE | DER_OCTET_STRING) is right. - */ - for (; *indp != NULL; indp++) { - SECItem *item; - item = (SECItem *)(*indp); - sub_len = item->len; - if (under_kind == DER_BIT_STRING) { - sub_len = (sub_len + 7) >> 3; - /* bit string contents involve an extra octet */ - if (sub_len) - sub_len++; - } - if (under_kind != DER_ANY) - len += 1 + DER_LengthLength (sub_len); - } - } - - return len; - } - - switch (under_kind) { - case DER_SEQUENCE: - case DER_SET: - { - DERTemplate *tmpt; - void *sub_src; - uint32 sub_len; - - len = 0; - for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) { - sub_src = (void *)((char *)src + tmpt->offset); - sub_len = contents_length (tmpt, sub_src); - len += sub_len + header_length (tmpt, sub_len); - } - } - break; - - case DER_BIT_STRING: - len = (((SECItem *)src)->len + 7) >> 3; - /* bit string contents involve an extra octet */ - if (len) - len++; - break; - - default: - len = ((SECItem *)src)->len; - break; - } - - return len; -} - - -static unsigned char * -der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src) -{ - int header_len; - uint32 contents_len; - unsigned long encode_kind, under_kind; - PRBool explicit, optional, universal; - - - /* - * First figure out how long the encoding will be. Do this by - * traversing the template from top to bottom and accumulating - * the length of each leaf item. - */ - contents_len = contents_length (dtemplate, src); - header_len = header_length (dtemplate, contents_len); - - /* - * Enough smarts was involved already, so that if both the - * header and the contents have a length of zero, then we - * are not doing any encoding for this element. - */ - if (header_len == 0 && contents_len == 0) - return buf; - - encode_kind = dtemplate->kind; - - explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE; - optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE; - encode_kind &= ~DER_OPTIONAL; - universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL) - ? PR_TRUE : PR_FALSE; - - if (encode_kind & DER_POINTER) { - if (contents_len) { - src = *(void **)src; - PORT_Assert (src != NULL); - } - if (dtemplate->sub != NULL) { - dtemplate = dtemplate->sub; - under_kind = dtemplate->kind; - if (universal) { - encode_kind = under_kind; - } - src = (void *)((char *)src + dtemplate->offset); - } else if (universal) { - under_kind = encode_kind & ~DER_POINTER; - } else { - under_kind = dtemplate->arg; - } - } else if (encode_kind & DER_INLINE) { - dtemplate = dtemplate->sub; - under_kind = dtemplate->kind; - if (universal) { - encode_kind = under_kind; - } - src = (void *)((char *)src + dtemplate->offset); - } else if (universal) { - under_kind = encode_kind; - } else { - under_kind = dtemplate->arg; - } - - if (explicit) { - buf = DER_StoreHeader (buf, encode_kind, - (1 + DER_LengthLength(contents_len) - + contents_len)); - encode_kind = under_kind; - } - - if ((encode_kind & DER_ANY) == 0) { /* DER_ANY already contains header */ - buf = DER_StoreHeader (buf, encode_kind, contents_len); - } - - /* If no real contents to encode, then we are done. */ - if (contents_len == 0) - return buf; - - if (under_kind & DER_INDEFINITE) { - void **indp; - - indp = *(void ***)src; - PORT_Assert (indp != NULL); - - under_kind &= ~DER_INDEFINITE; - if (under_kind == DER_SET || under_kind == DER_SEQUENCE) { - DERTemplate *tmpt; - void *sub_src; - - tmpt = dtemplate->sub; - for (; *indp != NULL; indp++) { - sub_src = (void *)((char *)(*indp) + tmpt->offset); - buf = der_encode (buf, tmpt, sub_src); - } - } else { - for (; *indp != NULL; indp++) { - SECItem *item; - int sub_len; - - item = (SECItem *)(*indp); - sub_len = item->len; - if (under_kind == DER_BIT_STRING) { - if (sub_len) { - int rem; - - sub_len = (sub_len + 7) >> 3; - buf = DER_StoreHeader (buf, under_kind, sub_len + 1); - rem = (sub_len << 3) - item->len; - *buf++ = rem; /* remaining bits */ - } else { - buf = DER_StoreHeader (buf, under_kind, 0); - } - } else if (under_kind != DER_ANY) { - buf = DER_StoreHeader (buf, under_kind, sub_len); - } - PORT_Memcpy (buf, item->data, sub_len); - buf += sub_len; - } - } - return buf; - } - - switch (under_kind) { - case DER_SEQUENCE: - case DER_SET: - { - DERTemplate *tmpt; - void *sub_src; - - for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) { - sub_src = (void *)((char *)src + tmpt->offset); - buf = der_encode (buf, tmpt, sub_src); - } - } - break; - - case DER_BIT_STRING: - { - SECItem *item; - int rem; - - /* - * The contents length includes our extra octet; subtract - * it off so we just have the real string length there. - */ - contents_len--; - item = (SECItem *)src; - PORT_Assert (contents_len == ((item->len + 7) >> 3)); - rem = (contents_len << 3) - item->len; - *buf++ = rem; /* remaining bits */ - PORT_Memcpy (buf, item->data, contents_len); - buf += contents_len; - } - break; - - default: - { - SECItem *item; - - item = (SECItem *)src; - PORT_Assert (contents_len == item->len); - PORT_Memcpy (buf, item->data, contents_len); - buf += contents_len; - } - break; - } - - return buf; -} - - -SECStatus -DER_Encode(PRArenaPool *arena, SECItem *dest, DERTemplate *dtemplate, void *src) -{ - unsigned int contents_len, header_len; - - src = (void **)((char *)src + dtemplate->offset); - - /* - * First figure out how long the encoding will be. Do this by - * traversing the template from top to bottom and accumulating - * the length of each leaf item. - */ - contents_len = contents_length (dtemplate, src); - header_len = header_length (dtemplate, contents_len); - - dest->len = contents_len + header_len; - - /* Allocate storage to hold the encoding */ - dest->data = (unsigned char*) PORT_ArenaAlloc(arena, dest->len); - if (dest->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - - /* Now encode into the buffer */ - (void) der_encode (dest->data, dtemplate, src); - - return SECSuccess; -} |