Back to index

lightning-sunbird  0.9+nobinonly
secasn1u.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038  * Utility routines to complement the ASN.1 encoding and decoding functions.
00039  *
00040  * $Id: secasn1u.c,v 1.4 2005/04/09 05:06:34 julien.pierre.bugs%sun.com Exp $
00041  */
00042 
00043 #include "secasn1.h"
00044 
00045 
00046 /*
00047  * We have a length that needs to be encoded; how many bytes will the
00048  * encoding take?
00049  *
00050  * The rules are that 0 - 0x7f takes one byte (the length itself is the
00051  * entire encoding); everything else takes one plus the number of bytes
00052  * in the length.
00053  */
00054 int
00055 SEC_ASN1LengthLength (unsigned long len)
00056 {
00057     int lenlen = 1;
00058 
00059     if (len > 0x7f) {
00060        do {
00061            lenlen++;
00062            len >>= 8;
00063        } while (len);
00064     }
00065 
00066     return lenlen;
00067 }
00068 
00069 
00070 /*
00071  * XXX Move over (and rewrite as appropriate) the rest of the
00072  * stuff in dersubr.c!
00073  */
00074 
00075 
00076 /*
00077  * Find the appropriate subtemplate for the given template.
00078  * This may involve calling a "chooser" function, or it may just
00079  * be right there.  In either case, it is expected to *have* a
00080  * subtemplate; this is asserted in debug builds (in non-debug
00081  * builds, NULL will be returned).
00082  *
00083  * "thing" is a pointer to the structure being encoded/decoded
00084  * "encoding", when true, means that we are in the process of encoding
00085  *     (as opposed to in the process of decoding)
00086  */
00087 const SEC_ASN1Template *
00088 SEC_ASN1GetSubtemplate (const SEC_ASN1Template *theTemplate, void *thing,
00089                      PRBool encoding)
00090 {
00091     const SEC_ASN1Template *subt = NULL;
00092 
00093     PORT_Assert (theTemplate->sub != NULL);
00094     if (theTemplate->sub != NULL) {
00095        if (theTemplate->kind & SEC_ASN1_DYNAMIC) {
00096            SEC_ASN1TemplateChooserPtr chooserp;
00097 
00098            chooserp = *(SEC_ASN1TemplateChooserPtr *) theTemplate->sub;
00099            if (chooserp) {
00100               if (thing != NULL)
00101                   thing = (char *)thing - theTemplate->offset;
00102               subt = (* chooserp)(thing, encoding);
00103            }
00104        } else {
00105            subt = (SEC_ASN1Template*)theTemplate->sub;
00106        }
00107     }
00108     return subt;
00109 }
00110 
00111 PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate)
00112 {
00113     if (!theTemplate) {
00114        return PR_TRUE; /* it doesn't get any simpler than NULL */
00115     }
00116     /* only templates made of one primitive type or a choice of primitive
00117        types are considered simple */
00118     if (! (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) {
00119        return PR_TRUE; /* primitive type */
00120     }
00121     if (!theTemplate->kind & SEC_ASN1_CHOICE) {
00122        return PR_FALSE; /* no choice means not simple */
00123     }
00124     while (++theTemplate && theTemplate->kind) {
00125        if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
00126            return PR_FALSE; /* complex type */
00127        }
00128     }
00129     return PR_TRUE; /* choice of primitive types */
00130 }
00131