1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19/*
20 * DecodedCrl.cpp - object representing a decoded CRL, in NSS format,
21 * with extensions parsed and decoded (still in NSS format).
22 *
23 * Created 8/28/2002 by Doug Mitchell.
24 */
25
26#include "DecodedCrl.h"
27#include "cldebugging.h"
28#include "AppleX509CLSession.h"
29#include "CSPAttacher.h"
30#include <Security/cssmapple.h>
31
32DecodedCrl::DecodedCrl(
33	AppleX509CLSession	&session)
34	: DecodedItem(session)
35{
36	memset(&mCrl, 0, sizeof(mCrl));
37}
38
39/* one-shot constructor, decoding from DER-encoded data */
40DecodedCrl::DecodedCrl(
41	AppleX509CLSession	&session,
42	const CssmData 		&encodedCrl)
43	: DecodedItem(session)
44{
45	memset(&mCrl, 0, sizeof(mCrl));
46	PRErrorCode prtn = mCoder.decode(encodedCrl.data(), encodedCrl.length(),
47		kSecAsn1SignedCrlTemplate, &mCrl);
48	if(prtn) {
49		CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
50	}
51	mDecodedExtensions.decodeFromNss(mCrl.tbs.extensions);
52	mState = IS_DecodedAll;
53}
54
55DecodedCrl::~DecodedCrl()
56{
57}
58
59/* decode mCrl.tbs and its extensions */
60void DecodedCrl::decodeCts(
61	const CssmData	&encodedCts)
62{
63	assert(mState == IS_Empty);
64	memset(&mCrl, 0, sizeof(mCrl));
65	PRErrorCode prtn = mCoder.decode(encodedCts.data(), encodedCts.length(),
66		kSecAsn1TBSCrlTemplate, &mCrl.tbs);
67	if(prtn) {
68		CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
69	}
70	mDecodedExtensions.decodeFromNss(mCrl.tbs.extensions);
71	mState = IS_DecodedTBS;
72}
73
74void DecodedCrl::encodeExtensions()
75{
76	NSS_TBSCrl &tbs = mCrl.tbs;
77	assert(mState == IS_Building);
78	assert(tbs.extensions == NULL);
79
80	if(mDecodedExtensions.numExtensions() == 0) {
81		/* no extensions, no error */
82		return;
83	}
84	mDecodedExtensions.encodeToNss(tbs.extensions);
85}
86
87/*
88 * FIXME : how to determine max encoding size at run time!?
89 */
90#define MAX_TEMPLATE_SIZE	(16 * 1024)
91
92/* encode TBS component; only called from CrlCreateTemplate */
93void DecodedCrl::encodeCts(
94	CssmOwnedData	&encodedCts)
95{
96	encodeExtensions();
97	assert(mState == IS_Building);
98
99	/* enforce required fields - could go deeper, maybe we should */
100	NSS_TBSCrl &tbs = mCrl.tbs;
101	if((tbs.signature.algorithm.Data == NULL) ||
102	   (tbs.issuer.rdns == NULL)) {
103		clErrorLog("DecodedCrl::encodeTbs: incomplete TBS");
104		/* an odd, undocumented error return */
105		CssmError::throwMe(CSSMERR_CL_NO_FIELD_VALUES);
106	}
107
108	PRErrorCode prtn;
109	prtn = SecNssEncodeItemOdata(&tbs, kSecAsn1TBSCrlTemplate,
110		encodedCts);
111	if(prtn) {
112		CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
113	}
114}
115
116