security/nss/lib/certdb/xbsconst.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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/. */
     5 /*
     6  * X.509 v3 Basic Constraints Extension 
     7  */
     9 #include "prtypes.h"
    10 #include <limits.h>     /* for LONG_MAX */
    11 #include "seccomon.h"
    12 #include "secdert.h"
    13 #include "secoidt.h"
    14 #include "secasn1t.h"
    15 #include "secasn1.h"
    16 #include "certt.h"
    17 #include "secder.h"
    18 #include "prprf.h"
    19 #include "secerr.h"
    21 typedef struct EncodedContext{
    22     SECItem isCA;
    23     SECItem pathLenConstraint;
    24     SECItem encodedValue;
    25     PLArenaPool *arena;
    26 }EncodedContext;
    28 static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = {
    29     { SEC_ASN1_SEQUENCE,
    30 	  0, NULL, sizeof(EncodedContext) },
    31     { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,		/* XXX DER_DEFAULT */
    32 	  offsetof(EncodedContext,isCA)},
    33     { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
    34 	  offsetof(EncodedContext,pathLenConstraint) },
    35     { 0, }
    36 };
    38 static unsigned char hexTrue = 0xff;
    39 static unsigned char hexFalse = 0x00;
    41 #define GEN_BREAK(status) rv = status; break;
    43 SECStatus CERT_EncodeBasicConstraintValue
    44    (PLArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue)
    45 {
    46     EncodedContext encodeContext;
    47     PLArenaPool *our_pool = NULL;
    48     SECStatus rv = SECSuccess;
    50     do {
    51 	PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
    52 	if (!value->isCA && value->pathLenConstraint >= 0) {
    53 	    PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
    54 	    GEN_BREAK (SECFailure);
    55 	}
    57         encodeContext.arena = arena;
    58 	if (value->isCA == PR_TRUE) {
    59 	    encodeContext.isCA.data =  &hexTrue ;
    60 	    encodeContext.isCA.len = 1;
    61 	}
    63 	/* If the pathLenConstraint is less than 0, then it should be
    64 	 * omitted from the encoding.
    65 	 */
    66 	if (value->isCA && value->pathLenConstraint >= 0) {
    67 	    our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
    68 	    if (our_pool == NULL) {
    69 		PORT_SetError (SEC_ERROR_NO_MEMORY);
    70 		GEN_BREAK (SECFailure);
    71 	    }
    72 	    if (SEC_ASN1EncodeUnsignedInteger
    73 		(our_pool, &encodeContext.pathLenConstraint,
    74 		 (unsigned long)value->pathLenConstraint) == NULL) {
    75 		PORT_SetError (SEC_ERROR_NO_MEMORY);
    76 		GEN_BREAK (SECFailure);
    77 	    }
    78 	}
    79 	if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
    80 				CERTBasicConstraintsTemplate) == NULL) {
    81 	    GEN_BREAK (SECFailure);
    82 	}
    83     } while (0);
    84     if (our_pool)
    85 	PORT_FreeArena (our_pool, PR_FALSE);
    86     return(rv);
    88 }
    90 SECStatus CERT_DecodeBasicConstraintValue
    91    (CERTBasicConstraints *value, const SECItem *encodedValue)
    92 {
    93     EncodedContext decodeContext;
    94     PLArenaPool *our_pool;
    95     SECStatus rv = SECSuccess;
    97     do {
    98 	PORT_Memset (&decodeContext, 0, sizeof (decodeContext));
    99 	/* initialize the value just in case we got "0x30 00", or when the
   100 	   pathLenConstraint is omitted.
   101          */
   102 	decodeContext.isCA.data =&hexFalse;
   103 	decodeContext.isCA.len = 1;
   105 	our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
   106 	if (our_pool == NULL) {
   107 	    PORT_SetError (SEC_ERROR_NO_MEMORY);
   108 	    GEN_BREAK (SECFailure);
   109 	}
   111         rv = SEC_QuickDERDecodeItem
   112 	     (our_pool, &decodeContext, CERTBasicConstraintsTemplate, encodedValue);
   113 	if (rv == SECFailure)
   114 	    break;
   116 	value->isCA = decodeContext.isCA.data 
   117 	              ? (PRBool)(decodeContext.isCA.data[0] != 0)
   118 		      : PR_FALSE;
   119 	if (decodeContext.pathLenConstraint.data == NULL) {
   120 	    /* if the pathLenConstraint is not encoded, and the current setting
   121 	      is CA, then the pathLenConstraint should be set to a negative number
   122 	      for unlimited certificate path.
   123 	     */
   124 	    if (value->isCA)
   125 		value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
   126 	} else if (value->isCA) {
   127 	    long len = DER_GetInteger (&decodeContext.pathLenConstraint);
   128 	    if (len < 0 || len == LONG_MAX) {
   129 		PORT_SetError (SEC_ERROR_BAD_DER);
   130 		GEN_BREAK (SECFailure);
   131 	    }
   132 	    value->pathLenConstraint = len;
   133 	} else {
   134 	    /* here we get an error where the subject is not a CA, but
   135 	       the pathLenConstraint is set */
   136 	    PORT_SetError (SEC_ERROR_BAD_DER);
   137 	    GEN_BREAK (SECFailure);
   138 	    break;
   139 	}
   141     } while (0);
   142     PORT_FreeArena (our_pool, PR_FALSE);
   143     return (rv);
   145 }

mercurial