/*
 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
 * 
 * The contents of this file constitute Original Code as defined in and are
 * subject to the Apple Public Source License Version 1.2 (the 'License').
 * You may not use this file except in compliance with the License. Please obtain
 * a copy of the License at http://www.apple.com/publicsource and read it before
 * using this file.
 * 
 * This Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
 * specific language governing rights and limitations under the License.
 */


//
// cssmcert - CSSM layer certificate (CL) related objects.
//
#ifndef _H_CSSMCERT
#define _H_CSSMCERT

#include <Security/utilities.h>
#include <Security/cssmalloc.h>


namespace Security {


//
// A CSSM_FIELD, essentially an OID/Data pair.
//
class CssmField : public PodWrapper<CssmField, CSSM_FIELD> {
public:
    CssmField() { }
    CssmField(const CSSM_OID &oid, const CSSM_DATA &value)
    { FieldOid = oid; FieldValue = value; }
    
    CssmField(const CSSM_OID &oid)
    { FieldOid = oid; FieldValue = CssmData(); }

public:
    CssmOid &oid()					{ return CssmOid::overlay(FieldOid); }
    CssmOid &value()				{ return CssmOid::overlay(FieldValue); }
    const CssmOid &oid() const		{ return CssmOid::overlay(FieldOid); }
    const CssmOid &value() const	{ return CssmOid::overlay(FieldValue); }
    
    bool isComplex() const
    { return value().length() == CSSM_FIELDVALUE_COMPLEX_DATA_TYPE; }
};


//
// An encoded certificate
//
class EncodedCertificate : public PodWrapper<EncodedCertificate, CSSM_ENCODED_CERT> {
public:
	EncodedCertificate(CSSM_CERT_TYPE type = CSSM_CERT_UNKNOWN,
		CSSM_CERT_ENCODING enc = CSSM_CERT_ENCODING_UNKNOWN,
		const CSSM_DATA *data = NULL);
	
	CSSM_CERT_TYPE type() const		{ return CertType; }
	CSSM_CERT_ENCODING encoding() const { return CertEncoding; }
	const CssmData &blob() const	{ return CssmData::overlay(CertBlob); }
	
	// CssmDataoid features
	void *data() const				{ return blob().data(); }
	size_t length() const			{ return blob().length(); }
};


//
// CertGroups - groups of certificates in a bewildering variety of forms
//
class CertGroup : public PodWrapper<CertGroup, CSSM_CERTGROUP> {
public:
    CertGroup() { }
    CertGroup(CSSM_CERT_TYPE ctype, CSSM_CERT_ENCODING encoding, CSSM_CERTGROUP_TYPE type);
    
public:
    CSSM_CERT_TYPE certType() const		{ return CertType; }
    CSSM_CERT_ENCODING encoding() const	{ return CertEncoding; }
    CSSM_CERTGROUP_TYPE type() const	{ return CertGroupType; }
    uint32 count() const				{ return NumCerts; }
    uint32 &count()						{ return NumCerts; }
    
public:
	// CSSM_CERTGROUP_DATA version
    CssmData * &blobCerts()
	{ assert(type() == CSSM_CERTGROUP_DATA); return CssmData::overlayVar(GroupList.CertList); }
    CssmData *blobCerts() const
	{ assert(type() == CSSM_CERTGROUP_DATA); return CssmData::overlay(GroupList.CertList); }
	
	// CSSM_CERTGROUP_ENCODED_CERT version
    EncodedCertificate * &encodedCerts()
		{ return EncodedCertificate::overlayVar(GroupList.EncodedCertList); }
    EncodedCertificate *encodedCerts() const
		{ return EncodedCertificate::overlay(GroupList.EncodedCertList); }
	
public:
	// free all memory in this group with the given allocator
	void destroy(CssmAllocator &allocator);
};


//
// Walkers
//
namespace DataWalkers {




}	// end namespace DataWalkers
}	// end namespace Security

#endif //_H_CSSMCERT
