PageRenderTime 31ms CodeModel.GetById 16ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/security/nss/cmd/lib/pppolicy.c

http://github.com/zpao/v8monkey
C | 299 lines | 205 code | 36 blank | 58 comment | 47 complexity | 7801cfb83fb4a9dac1aab45ea717b7d3 MD5 | raw file
  1/* ***** BEGIN LICENSE BLOCK *****
  2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3 *
  4 * The contents of this file are subject to the Mozilla Public License Version
  5 * 1.1 (the "License"); you may not use this file except in compliance with
  6 * the License. You may obtain a copy of the License at
  7 * http://www.mozilla.org/MPL/
  8 *
  9 * Software distributed under the License is distributed on an "AS IS" basis,
 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 11 * for the specific language governing rights and limitations under the
 12 * License.
 13 *
 14 * The Original Code is the Netscape security libraries.
 15 *
 16 * The Initial Developer of the Original Code is
 17 * Netscape Communications Corporation.
 18 * Portions created by the Initial Developer are Copyright (C) 2004
 19 * the Initial Developer. All Rights Reserved.
 20 *
 21 * Contributor(s):
 22 *
 23 * Alternatively, the contents of this file may be used under the terms of
 24 * either the GNU General Public License Version 2 or later (the "GPL"), or
 25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 26 * in which case the provisions of the GPL or the LGPL are applicable instead
 27 * of those above. If you wish to allow use of your version of this file only
 28 * under the terms of either the GPL or the LGPL, and not to allow others to
 29 * use your version of this file under the terms of the MPL, indicate your
 30 * decision by deleting the provisions above and replace them with the notice
 31 * and other provisions required by the GPL or the LGPL. If you do not delete
 32 * the provisions above, a recipient may use your version of this file under
 33 * the terms of any one of the MPL, the GPL or the LGPL.
 34 *
 35 * ***** END LICENSE BLOCK ***** */
 36
 37/*
 38 * Support for various policy related extensions
 39 *
 40 * $Id: pppolicy.c,v 1.5 2011/11/16 19:12:30 kaie%kuix.de Exp $
 41 */
 42
 43#include "seccomon.h"
 44#include "secport.h"
 45#include "secder.h"
 46#include "cert.h"
 47#include "secoid.h"
 48#include "secasn1.h"
 49#include "secerr.h"
 50#include "nspr.h"
 51#include "secutil.h"
 52
 53/* This implementation is derived from the one in nss/lib/certdb/policyxtn.c .
 54** The chief difference is the addition of the OPTIONAL flag to many 
 55** parts.  The idea is to be able to parse and print as much of the 
 56** policy extension as possible, even if some parts are invalid.
 57**
 58** If this approach still is unable to decode policy extensions that
 59** contain invalid parts, then the next approach will be to parse 
 60** the PolicyInfos as a SEQUENCE of ANYs, and then parse each of them 
 61** as PolicyInfos, with the PolicyQualifiers being ANYs, and finally
 62** parse each of the PolicyQualifiers.
 63*/
 64
 65static const SEC_ASN1Template secu_PolicyQualifierTemplate[] = {
 66    { SEC_ASN1_SEQUENCE,
 67	  0, NULL, sizeof(CERTPolicyQualifier) },
 68    { SEC_ASN1_OBJECT_ID,
 69	  offsetof(CERTPolicyQualifier, qualifierID) },
 70    { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
 71	  offsetof(CERTPolicyQualifier, qualifierValue) },
 72    { 0 }
 73};
 74
 75static const SEC_ASN1Template secu_PolicyInfoTemplate[] = {
 76    { SEC_ASN1_SEQUENCE,
 77	  0, NULL, sizeof(CERTPolicyInfo) },
 78    { SEC_ASN1_OBJECT_ID,
 79	  offsetof(CERTPolicyInfo, policyID) },
 80    { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
 81	  offsetof(CERTPolicyInfo, policyQualifiers),
 82	  secu_PolicyQualifierTemplate },
 83    { 0 }
 84};
 85
 86static const SEC_ASN1Template secu_CertificatePoliciesTemplate[] = {
 87    { SEC_ASN1_SEQUENCE_OF,
 88	  offsetof(CERTCertificatePolicies, policyInfos),
 89	  secu_PolicyInfoTemplate, sizeof(CERTCertificatePolicies)  }
 90};
 91
 92
 93static CERTCertificatePolicies *
 94secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
 95{
 96    PRArenaPool *arena = NULL;
 97    SECStatus rv;
 98    CERTCertificatePolicies *policies;
 99    CERTPolicyInfo **policyInfos, *policyInfo;
100    CERTPolicyQualifier **policyQualifiers, *policyQualifier;
101    SECItem newExtnValue;
102    
103    /* make a new arena */
104    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
105    
106    if ( !arena ) {
107	goto loser;
108    }
109
110    /* allocate the certifiate policies structure */
111    policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
112    if ( policies == NULL ) {
113	goto loser;
114    }
115    
116    policies->arena = arena;
117
118    /* copy the DER into the arena, since Quick DER returns data that points
119       into the DER input, which may get freed by the caller */
120    rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
121    if ( rv != SECSuccess ) {
122	goto loser;
123    }
124
125    /* decode the policy info */
126    rv = SEC_QuickDERDecodeItem(arena, policies, 
127                                secu_CertificatePoliciesTemplate,
128			        &newExtnValue);
129
130    if ( rv != SECSuccess ) {
131	goto loser;
132    }
133
134    /* initialize the oid tags */
135    policyInfos = policies->policyInfos;
136    while (policyInfos != NULL && *policyInfos != NULL ) {
137	policyInfo = *policyInfos;
138	policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
139	policyQualifiers = policyInfo->policyQualifiers;
140	while ( policyQualifiers && *policyQualifiers != NULL ) {
141	    policyQualifier = *policyQualifiers;
142	    policyQualifier->oid =
143		SECOID_FindOIDTag(&policyQualifier->qualifierID);
144	    policyQualifiers++;
145	}
146	policyInfos++;
147    }
148
149    return(policies);
150    
151loser:
152    if ( arena != NULL ) {
153	PORT_FreeArena(arena, PR_FALSE);
154    }
155    
156    return(NULL);
157}
158
159
160static char *
161itemToString(SECItem *item)
162{
163    char *string;
164
165    string = PORT_ZAlloc(item->len+1);
166    if (string == NULL) return NULL;
167    PORT_Memcpy(string,item->data,item->len);
168    string[item->len] = 0;
169    return string;
170}
171
172static SECStatus
173secu_PrintUserNoticeQualifier(FILE *out, SECItem * qualifierValue,
174                              char *msg, int level)
175{
176    CERTUserNotice *userNotice = NULL;
177    if (qualifierValue)
178	userNotice = CERT_DecodeUserNotice(qualifierValue);
179    if (userNotice) {
180	if (userNotice->noticeReference.organization.len != 0) {
181            char *string = 
182	            itemToString(&userNotice->noticeReference.organization);
183            SECItem **itemList = userNotice->noticeReference.noticeNumbers;
184
185	    while (itemList && *itemList) {
186		SECU_PrintInteger(out,*itemList,string,level+1);
187	        itemList++;
188	    }
189	    PORT_Free(string);
190	}
191	if (userNotice->displayText.len != 0) {
192	    SECU_PrintString(out,&userNotice->displayText,
193			     "Display Text", level+1);
194	}
195	CERT_DestroyUserNotice(userNotice);
196	return SECSuccess;
197    }
198    return SECFailure;	/* caller will print this value */
199}
200
201static SECStatus
202secu_PrintPolicyQualifier(FILE *out,CERTPolicyQualifier *policyQualifier,
203			  char *msg,int level)
204{
205   SECStatus rv;
206   SECItem * qualifierValue = &policyQualifier->qualifierValue;
207
208   SECU_PrintObjectID(out, &policyQualifier->qualifierID , 
209					"Policy Qualifier Name", level);
210   if (!qualifierValue->data) {
211	SECU_Indent(out, level);
212	fprintf(out,"Error: missing qualifier\n");
213   } else 
214   switch (policyQualifier->oid) {
215   case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
216       rv = secu_PrintUserNoticeQualifier(out, qualifierValue, msg, level);
217       if (SECSuccess == rv)
218	   break;
219       /* fall through on error */
220   case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
221   default:
222	SECU_PrintAny(out, qualifierValue, "Policy Qualifier Data", level);
223	break;
224   }
225   return SECSuccess;
226}
227
228static SECStatus
229secu_PrintPolicyInfo(FILE *out,CERTPolicyInfo *policyInfo,char *msg,int level)
230{
231   CERTPolicyQualifier **policyQualifiers;
232
233   policyQualifiers = policyInfo->policyQualifiers;
234   SECU_PrintObjectID(out, &policyInfo->policyID , "Policy Name", level);
235   
236   while (policyQualifiers && *policyQualifiers != NULL) {
237	secu_PrintPolicyQualifier(out,*policyQualifiers,"",level+1);
238	policyQualifiers++;
239   }
240   return SECSuccess;
241}
242
243void
244SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level)
245{
246   CERTCertificatePolicies *policies = NULL;
247   CERTPolicyInfo **policyInfos;
248
249   if (msg) {
250	SECU_Indent(out, level);
251	fprintf(out,"%s: \n",msg);
252	level++;
253   }
254   policies = secu_DecodeCertificatePoliciesExtension(value);
255   if (policies == NULL) {
256	SECU_PrintAny(out, value, "Invalid Policy Data", level);
257	return;
258   }
259
260   policyInfos = policies->policyInfos;
261   while (policyInfos && *policyInfos != NULL) {
262	secu_PrintPolicyInfo(out,*policyInfos,"",level);
263	policyInfos++;
264   }
265
266   CERT_DestroyCertificatePoliciesExtension(policies);
267}
268
269
270void
271SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value, 
272			              char *msg, int level)
273{
274    CERTPrivKeyUsagePeriod * prd;
275    PLArenaPool * arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
276
277    if ( !arena ) {
278	goto loser;
279    }
280    prd = CERT_DecodePrivKeyUsagePeriodExtension(arena, value);
281    if (!prd) {
282	goto loser;
283    }
284    if (prd->notBefore.data) {
285	SECU_PrintGeneralizedTime(out, &prd->notBefore, "Not Before", level);
286    }
287    if (prd->notAfter.data) {
288	SECU_PrintGeneralizedTime(out, &prd->notAfter,  "Not After ", level);
289    }
290    if (!prd->notBefore.data && !prd->notAfter.data) {
291	SECU_Indent(out, level);
292	fprintf(out, "Error: notBefore or notAfter MUST be present.\n");
293loser:
294	SECU_PrintAny(out, value, msg, level);
295    }
296    if (arena) {
297	PORT_FreeArena(arena, PR_FALSE);
298    }
299}