-- partially automatically generated by posy 5.0 #6 (Prag)!

--
--                Certificates and Related Types from:
--            X.509 The Directory - Authentication Framework
--                  Subset of Definitions in Annex G
--
--                PKRoot and PKList from SecureDFN Project

-- AuthenticationFramework
AF    DEFINITIONS ::=

%{	/* surrounding global definitions	*/
#include        "af.h"

static PE            build_revlist_tbs(), build_revcert_tbs(), build_tbs();
static PE 	     build_pemcrl_tbs();
PE                   aux_OctetString2PE();
struct type_IF_Name *aux_Name2DName();
char                *aux_DName2Name();
OctetString         *aux_PE2OctetString();
%}

BEGIN
-- EXPORTS
--              Validity, TBSCertificate, Certificate, Certificates,
--              ForwardCertificationPath, CrossCertificates, CrossCertificatePair,
--              TBSCrl, Crl, 
--              RevCert, TBSRevCert,
--              TBSPemCrl, PemCrl, RevCertPem,
--              RevCertSequence, OldCertificateList,
--              SerialSet, CrlSet, CrlPSE, PemCrlWithCerts
--
-- IMPORTS	
--		Name
--			FROM InformationFramework(IF)
--
--              UTCTime, BITSTRING, OctetString, INTEGER
--			FROM UNIV
--
--              AlgorithmIdentifier, KeyInfo
--                      FROM SecurityFramework(SEC)
--
-- functions symmetric for both parsing and building
SECTIONS build  parse none



Validity [[ P ToBeSigned * ]] ::=
        SEQUENCE {
            notBefore
                UTCTime
                [[s parm -> notbefore ]],

            notAfter
                UTCTime
                [[s parm -> notafter ]]
        }

PKRootValidity [[ P Serial * ]] ::=
        SEQUENCE {
            notBefore
                UTCTime
                [[s parm -> notbefore ]],

            notAfter
                UTCTime
                [[s parm -> notafter ]]
        }

ENCODER build

SerialNumbers [[ P SerialNumbers *]] ::=
	SEQUENCE {
                [0] INTEGER
                [[i parm->initial ]]
		DEFAULT 0 <<parm->initial != 0>>,

                [1] INTEGER
                [[i parm->actual ]]
	}


PKRoot [[P PKRoot *]] ::=
        SEQUENCE {
            cA
                IF.Name
                [[p parm -> ca ]],

            newkey
                RootKey
                [[p parm -> newkey ]],

            oldkey
                RootKey
                [[p parm -> oldkey ]]
                OPTIONAL <<parm -> oldkey>>
        }


RootKey [[P struct Serial *]] ::=
        SEQUENCE {
            version
		[0] INTEGER
                [[i parm->version ]]
                {
                    v1988(0)
                }
                DEFAULT v1988 <<parm->version != 0>>,

            serial
                INTEGER
                [[i parm->serial ]],

            key
                SEC.KeyInfo
                [[p parm->key ]],

            validity
                [1] PKRootValidity
                [[p parm ]]
		OPTIONAL <<parm->notbefore>>,

	    signAlgID
                [2] SEC.AlgorithmIdentifier
                [[p parm->sig->signAI ]]
		OPTIONAL <<parm->sig>>,

	    signBitString
		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
		OPTIONAL <<parm -> sig>>
        }


TBSCertificate [[P ToBeSigned *]] ::=
        SEQUENCE {
            version[0]
                INTEGER
                [[i parm -> version ]]
                {
                    v1988(0)
                }
                DEFAULT v1988 <<parm -> version != 0>>,

            serialNumber
                INTEGER
                [[i parm -> serialnumber ]],

            signature
                SEC.AlgorithmIdentifier
                [[p parm -> signatureAI ]],

            issuer
                IF.Name
                [[p parm -> issuer ]],

            validity
                Validity
                [[p parm ]],

            subject
                IF.Name
                [[p parm -> subject ]],

            subjectPublickeyInfo
                SEC.KeyInfo
                [[p parm -> subjectPK ]]
        }


Certificate [[P Certificate *]]
%{	PE	tbs;
%}
    ::= SEQUENCE { -- SIGNED
		-- TBSCertificate
		ANY
		[[ a (build_tbs(parm,&tbs)) ]]
		%{    pe_free(tbs);
		%} ,

                SEC.AlgorithmIdentifier
                [[p parm -> sig ->signAI ]],

		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]

        }


Certificates [[P Certificates *]] ::=
        SEQUENCE {
            certificate
                Certificate
                [[p parm -> usercertificate ]],

            certificationPath
                ForwardCertificationPath
                [[p parm -> forwardpath ]]
                OPTIONAL <<parm -> forwardpath>>
        }


ForwardCertificationPath [[P FCPath *]] ::=
        SEQUENCE OF
            <<; parm; parm = parm -> next_forwardpath>>
            CertificateSet
            [[p parm -> liste ]]


CertificateSet [[P SET_OF_Certificate *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            Certificate
            [[p parm -> element ]]


CertificatePair [[P CertificatePair *]] ::=
        SEQUENCE {
            forward
                [0] Certificate
                [[p parm -> forward ]]
		OPTIONAL <<parm -> forward>>,

            reverse
                [1] Certificate
                [[p parm -> reverse ]]
		OPTIONAL <<parm -> reverse>>
        }


CrossCertificatePair [[P SET_OF_CertificatePair *]] ::=
	SET OF
	    <<; parm; parm = parm -> next>>
	    CertificatePair
	    [[p parm -> element ]]


PKList [[P PKList *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            TBSCertificate
            [[p parm -> element ]]


TBSCrl [[ P CrlTBS *]]
    ::=     -- SIGNED type
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p parm->signatureAI ]],

            issuer
		IF.Name
		[[ p parm->issuer ]],

            lastUpdate
                UTCTime
		[[ s parm->lastupdate ]],

            revokedCertificates
		RevCertSequence
		[[ p parm->revokedcertificates ]]
		OPTIONAL <<parm->revokedcertificates>>
        }


Crl [[ P Crl *]]
    %{
	PE tbs;
    %}
    ::=
	SEQUENCE   -- SIGNED
	{       -- TBSCrl
                ANY
		[[ a (build_revlist_tbs(parm,&tbs)) ]]
		%{   pe_free(tbs);
		%},

                SEC.AlgorithmIdentifier
		[[ p parm->sig->signAI ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
	}  -- end of SIGNED


TBSRevCert [[ P RevCertTBS *]] ::=
	SEQUENCE  -- SIGNED type
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p parm->signatureAI ]],

            issuer
		IF.Name
		[[ p parm->issuer ]],

            subject
                INTEGER
		[[ i parm->subject ]],

	    revocationDate
                UTCTime
		[[ s parm->revocationdate ]]
        }


RevCert [[ P RevCert *]]
    %{
	PE tbs;
    %}
    ::=
	SEQUENCE   -- SIGNED
	{       -- TBSRevCert
                ANY
		[[ a (build_revcert_tbs(parm,&tbs)) ]]
		%{   pe_free(tbs);
		%},

                SEC.AlgorithmIdentifier
		[[ p parm->sig->signAI ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertSequence [[ P SEQUENCE_OF_RevCert *]]
    ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    RevCert
	    [[ p (parm->element) ]]


TBSPemCrl [[ P PemCrlTBS *]]
    ::=     -- SIGNED type
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p parm->signatureAI ]],

            issuer
		IF.Name
		[[ p parm->issuer ]],

            lastUpdate
                UTCTime
		[[ s parm->lastUpdate ]],

	    nextUpdate
                UTCTime
		[[ s parm->nextUpdate ]],

            revokedCertificates
		RevCertPemSequence
		[[ p parm->revokedCertificates ]]
		OPTIONAL <<parm->revokedCertificates>>
        }


PemCrl [[ P PemCrl *]]
    %{
	PE tbs;
    %}
    ::=
	SEQUENCE   -- SIGNED
	{       -- TBSCrl
                ANY
		[[ a (build_pemcrl_tbs(parm,&tbs)) ]]
		%{   pe_free(tbs);
		%},

                SEC.AlgorithmIdentifier
		[[ p parm->sig->signAI ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertPem [[ P RevCertPem *]] ::=
	SEQUENCE
        {
            serialNumber
                INTEGER
		[[ i parm->serialnumber ]],

	    revocationDate
                UTCTime
		[[ s parm->revocationDate ]]
        }


RevCertPemSequence [[ P SEQUENCE_OF_RevCertPem *]]
    ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    RevCertPem
	    [[ p (parm->element) ]]


SerialSet [[P SET_OF_int *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            INTEGER
            [[i parm -> element ]]


CrlPSE [[P CrlPSE *]] ::=
	SEQUENCE
        {
            issuer
		IF.Name
		[[ p parm->issuer ]],

            nextUpdate
                UTCTime
		[[ s parm->nextUpdate ]],

	    revcerts
		RevCertPemSequence
		[[ p parm->revcerts ]]
		OPTIONAL <<parm->revcerts>>
        }


CrlSet [[P CrlSet *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            CrlPSE
            [[p parm -> element ]]


OldCertificateList [[ P OCList *]]
    ::=
        SEQUENCE OF
	    <<; parm; parm = parm->next>>
            SEQUENCE
            {
                serialNumber
                    INTEGER
		    [[ i parm->serialnumber ]],

                crossCertificate
                    AF.Certificate
		    [[ p parm->ccert ]]
            }


CertificationPath [[P CertificationPath *]] ::=
	SEQUENCE {
            userCertificate
                Certificate
                [[p parm->userCertificate ]],

            theCACertificates
                CertificatePairs
                [[p parm->theCACertificates ]]
		OPTIONAL <<parm->theCACertificates>>
        }


CertificatePairs [[ P CertificatePairs *]] 
%{
SEQUENCE_OF_CertificatePair * level;
%}
	::=
	SEQUENCE OF
		<<level = (parm)? parm->liste:(SEQUENCE_OF_CertificatePair * )0; 
		  level; 
		  level = (level->next)? level->next:((parm = parm->superior)? parm->liste:(SEQUENCE_OF_CertificatePair * )0)>>
		CertificatePair
		[[ p level->element ]]


PemCrlWithCerts [[P PemCrlWithCerts *]] ::=
	SEQUENCE {
            pemCRL
                PemCrl
                [[p parm->pemcrl ]],

            certificates
                Certificates
                [[p parm->certificates ]]
		OPTIONAL <<parm->certificates>>
        }


AliasesMember [[P Aliases *]] ::=
	SEQUENCE {
	    aname
		IA5String
		[[s parm->aname]],

	    aliasfile
		ENUMERATED
		[[i parm->aliasfile]]
		{
			useralias (0),
			sytemalias (1)
		}
	}


Aliases [[P Aliases *]] ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    AliasesMember
	    [[ p parm]]


AliasListMember [[P AliasList *]] ::=
	SEQUENCE {
	    aliases
		Aliases
		[[p parm->a]],

	    dname
		IA5String
		[[s parm->dname]]
	}


AliasList [[P AliasList *]] ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    AliasListMember
	    [[ p parm]]



DECODER parse


SerialNumbers [[ P SerialNumbers **]] ::=
    %{
        if ((*(parm) = (SerialNumbers *)
                calloc (1, sizeof **(parm))) == ((SerialNumbers *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm)->initial = 0;
    %}
        SEQUENCE {
                [0] INTEGER
                [[i (* parm)->initial ]]
		DEFAULT 0,

                [1] INTEGER
                [[i (* parm)->actual ]]
	}


PKRoot [[P PKRoot **]] ::=
    %{
        if ((*(parm) = (PKRoot *)
                calloc (1, sizeof **(parm))) == ((PKRoot *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE {
            cA
                IF.Name
                [[p &((*parm) -> ca)]],

            newkey
                RootKey
                [[p &((*parm) -> newkey)]],

            oldkey
                RootKey
                [[p &((*parm) -> oldkey)]]
                OPTIONAL
        }


RootKey [[P struct Serial **]] ::=
    %{
        if ((*(parm) = (struct Serial *)
                calloc (1, sizeof **(parm))) == ((struct Serial *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->key = (KeyInfo *)
                calloc (1, sizeof (KeyInfo))) == ((KeyInfo *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->sig = (Signature *)
                calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm)->notbefore = CNULL;
	(*parm)->notafter = CNULL;
	(*parm)->sig->signAI = NULLALGID;
	(*parm)->sig->signature.bits = CNULL;
	(*parm)->sig->signature.nbits = 0;
    %}
        SEQUENCE {
            version
		[0] INTEGER
                [[i (*parm)->version ]]
                {
                    v1988(0),v1992(1)
                }
                DEFAULT v1988,

            serial
                INTEGER
                [[i (*parm)->serial ]],

            key
                SEC.KeyInfo
                [[p ((*parm)->key)]],

            validity
                [1] PKRootValidity
                [[p (*parm) ]]
		OPTIONAL,

	    signAlgID
                [2] SEC.AlgorithmIdentifier
                [[p &((*parm)->sig->signAI) ]]
		OPTIONAL,

	    signBitString
		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
		OPTIONAL <<(*parm)->sig->signAI>>
        }
    %{
	if(! (*parm)->sig->signAI){
		aux_free_KeyInfo( (KeyInfo **) & ((*parm)->sig) );
		(*parm)->sig = (Signature * ) 0;
	}
    %}


TBSCertificate [[P ToBeSigned **]] ::=
    %{
        if ((*(parm) = (ToBeSigned *)
                calloc (1, sizeof **(parm))) == ((ToBeSigned *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->subjectPK = (KeyInfo *)
                calloc (1, sizeof (KeyInfo))) == ((KeyInfo *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm) -> version = 0;
    %}
        SEQUENCE {
            version[0]
                INTEGER
                [[i (*parm) -> version ]]
                {
                    v1988(0),v1992(1)
                }
                DEFAULT v1988,

            serialNumber
                INTEGER
                [[i (*parm) -> serialnumber ]],

            signature
                SEC.AlgorithmIdentifier
                [[p &((*parm) -> signatureAI)]],

            issuer
                IF.Name
                [[p &((*parm) -> issuer)]],

            validity
                Validity
                [[p (*parm) ]],

            subject
                IF.Name
                [[p &((*parm) -> subject)]],

            subjectPublickeyInfo
                SEC.KeyInfo
                [[p ((*parm) -> subjectPK)]]
        }


Certificate [[P Certificate **]] ::=
    %{
        if ((*(parm) = (Certificate *)
                calloc (1, sizeof **(parm))) == ((Certificate *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->sig = (Signature *)
                calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE { -- SIGNED
		TBSCertificate
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %}   ,

                SEC.AlgorithmIdentifier
                [[p &((*parm) -> sig->signAI)]],

		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
        }


Certificates [[P Certificates **]] ::=
    %{
        if ((*(parm) = (Certificates *)
                calloc (1, sizeof **(parm))) == ((Certificates *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE {
            certificate
                Certificate
                [[p &((*parm) -> usercertificate)]],

            certificationPath
                ForwardCertificationPath
                [[p &((*parm) -> forwardpath)]]
                OPTIONAL
        }


ForwardCertificationPath [[P FCPath **]] ::=
        SEQUENCE OF
            %{
                if ((*(parm) = (FCPath *)
                        calloc (1, sizeof **(parm))) == ((FCPath *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            CertificateSet
            [[p &((*parm) -> liste)]]
            %{ parm = &((*parm) -> next_forwardpath); %}


CertificateSet [[P SET_OF_Certificate **]] ::=
        SET OF
            %{
                if ((*(parm) = (SET_OF_Certificate *)
                        calloc (1, sizeof **(parm))) == ((SET_OF_Certificate *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            Certificate
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


CertificatePair [[P CertificatePair **]] ::=
    %{
        if ((*(parm) = (CertificatePair *)
                calloc (1, sizeof **(parm))) == ((CertificatePair *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE {
            forward
                [0] Certificate
                [[p &((*parm) -> forward)]]
		OPTIONAL,

            reverse
                [1] Certificate
                [[p &((*parm) -> reverse)]]
		OPTIONAL
        }


CrossCertificatePair [[P SET_OF_CertificatePair **]] ::=
        SET OF
            %{
                if ((*(parm) = (SET_OF_CertificatePair *)
                        calloc (1, sizeof **(parm))) == ((SET_OF_CertificatePair *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            CertificatePair
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


PKList [[P PKList **]] ::=
        SET OF
            %{
                if ((*(parm) = (PKList *)
                        calloc (1, sizeof **(parm))) == ((PKList *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            TBSCertificate
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


TBSCrl [[ P CrlTBS **]]
    ::=  -- SIGNED type
        %{
            if ((*(parm) = (CrlTBS *)
                    calloc (1, sizeof **(parm))) == ((CrlTBS *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
	    (*parm)->revokedcertificates = (SEQUENCE_OF_RevCert *)0;
	%}	
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->signatureAI) ]],

            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            lastUpdate
                UTCTime
		[[ s ((*parm)->lastupdate) ]],

            revokedCertificates
		RevCertSequence
		[[ p &((*parm)->revokedcertificates) ]]
		OPTIONAL
        }


Crl [[ P Crl **]] ::=
        %{
            if ((*(parm) = (Crl *)
                    calloc (1, sizeof **(parm))) == ((Crl *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
            if (((*parm)->sig = (Signature *)
                    calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}
	SEQUENCE  --SIGNED
        {
		TBSCrl
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if ( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %},
	   
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->sig->signAI) ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
	}  -- end of SIGNED


TBSRevCert [[ P RevCertTBS **]]
    ::=  -- SIGNED type
       %{
            if ((*(parm) = (RevCertTBS *)
                    calloc (1, sizeof **(parm))) == ((RevCertTBS *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
	%}
	SEQUENCE 
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->signatureAI) ]],

            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            subject
                INTEGER
		[[ i (*parm)->subject ]],

	    revocationDate
                UTCTime
		[[ s ((*parm)->revocationdate) ]]
        }


RevCert [[ P RevCert **]] ::=
        %{
            if ((*(parm) = (RevCert *)
                    calloc (1, sizeof **(parm))) == ((RevCert *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
            if (((*parm)->sig = (Signature *)
                    calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}
	SEQUENCE  -- SIGNED
        {
		TBSRevCert
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if ( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %},

                SEC.AlgorithmIdentifier
		[[ p &((*parm)->sig->signAI) ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertSequence [[ P SEQUENCE_OF_RevCert **]]
    ::=
        SEQUENCE OF
            %{
		if ((*(parm) = (SEQUENCE_OF_RevCert *)
			calloc (1, sizeof **(parm))) == (SEQUENCE_OF_RevCert *) 0) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
		(*parm) -> next = (SEQUENCE_OF_RevCert *)0;
            %}
	    RevCert
	    [[ p &((*parm) -> element) ]]
            %{ parm = &((*parm) -> next); %}


TBSPemCrl [[ P PemCrlTBS **]]
    ::=  -- SIGNED type
        %{
            if ((*(parm) = (PemCrlTBS *)
                    calloc (1, sizeof **(parm))) == ((PemCrlTBS *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
	    (*parm)->revokedCertificates = (SEQUENCE_OF_RevCertPem *)0;
	%}	
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->signatureAI) ]],

            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            lastUpdate
                UTCTime
		[[ s ((*parm)->lastUpdate) ]],

            nextUpdate
                UTCTime
		[[ s ((*parm)->nextUpdate) ]],

            revokedCertificates
		RevCertPemSequence
		[[ p &((*parm)->revokedCertificates) ]]
		OPTIONAL
        }


PemCrl [[ P PemCrl **]] ::=
        %{
            if ((*(parm) = (PemCrl *)
                    calloc (1, sizeof **(parm))) == ((PemCrl *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
            if (((*parm)->sig = (Signature *)
                    calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}
	SEQUENCE  --SIGNED
        {
		TBSPemCrl
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if ( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %},
	   
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->sig->signAI) ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertPemSequence [[ P SEQUENCE_OF_RevCertPem **]]
    ::=
        SEQUENCE OF
            %{
		if ((*(parm) = (SEQUENCE_OF_RevCertPem *)
			calloc (1, sizeof **(parm))) == (SEQUENCE_OF_RevCertPem *) 0) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
		(*parm) -> next = (SEQUENCE_OF_RevCertPem *)0;
            %}
	    RevCertPem
	    [[ p &((*parm) -> element) ]]
            %{ parm = &((*parm) -> next); %}


RevCertPem [[ P RevCertPem **]]
    ::= 
        %{
            if ((*(parm) = (RevCertPem *)
                    calloc (1, sizeof **(parm))) == ((RevCertPem *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}  
	SEQUENCE 
        {
            serialNumber
                INTEGER
		[[ i (*parm)->serialnumber ]],

	    revocationDate
                UTCTime
		[[ s (*parm)->revocationDate ]]
        }


SerialSet [[P SET_OF_int **]] ::=
        SET OF
            %{
                if ((*(parm) = (SET_OF_int *)
                        calloc (1, sizeof **(parm))) == ((SET_OF_int *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            INTEGER
            [[i (*parm) -> element ]]
            %{ parm = &((*parm) -> next); %}


CrlPSE [[ P CrlPSE **]]
    ::= 
        %{
            if ((*(parm) = (CrlPSE *)
                    calloc (1, sizeof **(parm))) == ((CrlPSE *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}  
	SEQUENCE 
        {
            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            nextUpdate
                UTCTime
		[[ s ((*parm)->nextUpdate) ]],

            revcerts
		RevCertPemSequence
		[[ p &((*parm)->revcerts) ]]
		OPTIONAL
        }


CrlSet [[P CrlSet **]] ::=
        SET OF
            %{
                if ((*(parm) = (CrlSet *)
                        calloc (1, sizeof **(parm))) == ((CrlSet *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            CrlPSE
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


OldCertificateList [[ P OCList **]]
    ::=
        SEQUENCE OF
            %{
		if ((*(parm) = (OCList *)
			calloc (1, sizeof **(parm))) == (OCList *) 0) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
		(*parm) -> next = (OCList *)0;
            %}
            SEQUENCE
            {
                serialNumber
                    INTEGER
		    [[ i (*parm) -> serialnumber ]],

                crossCertificate
                    AF.Certificate
		    [[ p &((*parm) -> ccert) ]]
            }
            %{ parm = &((*parm) -> next); %}


PemCrlWithCerts [[P PemCrlWithCerts **]] ::=
    %{
        if ((*(parm) = (PemCrlWithCerts *)
                calloc (1, sizeof **(parm))) == ((PemCrlWithCerts *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm)->certificates = (Certificates * )0;
    %}
        SEQUENCE {
            pemCRL
                PemCrl
                [[p &((*parm) -> pemcrl)]],

            certificates
                Certificates
                [[p &((*parm) -> certificates)]]
                OPTIONAL
        }


AliasesMember [[P Aliases *]] ::=
	SEQUENCE {
	    aname
		IA5String
		[[s parm->aname]],

	    aliasfile
		ENUMERATED
		[[i parm->aliasfile]]
		{
			useralias (0),
			systemalias (1)
		}
	}


Aliases [[P Aliases **]] ::=
	SEQUENCE OF
            %{
                if ((*(parm) = (Aliases *)
                        calloc (1, sizeof **(parm))) == ((Aliases *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
	    AliasesMember
	    [[ p *parm]]
            %{ parm = &((*parm) -> next); %}


AliasListMember [[P AliasList *]] ::=
	SEQUENCE {
	    aliases
		Aliases
		[[p &(parm->a)]],

	    dname
		IA5String
		[[s parm->dname]]
	}


AliasList [[P AliasList **]] ::=
	SEQUENCE OF
            %{
                if ((*(parm) = (AliasList *)
                        calloc (1, sizeof **(parm))) == ((AliasList *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
	    AliasListMember
	    [[ p *parm]]
            %{ parm = &((*parm) -> next); %}


END


%{
/************************ local functions: ****/

static
PE	build_tbs(cert,save)
Certificate      *cert;
PE               *save;
{
	(*save) = NULLPE;

	if( cert->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSCertificate(save,1,0,NULLCP, cert->tbs) == NOTOK)
		return NULLPE;
	    cert->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(cert->tbs_DERcode);

	return(*save);
}

static
PE      build_revlist_tbs(revlist,save)
Crl   *revlist;
PE        *save;
{
	(*save) = NULLPE;

	if( revlist->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSCrl(save,1,0,NULLCP,revlist->tbs) == NOTOK)
		return (NULLPE);
	    revlist->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(revlist->tbs_DERcode);

	return(*save);
}

static
PE      build_revcert_tbs(revcert,save)
RevCert      *revcert;
PE           *save;
{
	(*save) = NULLPE;

	if( revcert->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSRevCert(save,1,0,NULLCP,revcert->tbs) == NOTOK)
		return (NULLPE);
	    revcert->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(revcert->tbs_DERcode);

	return(*save);
}

static
PE	build_pemcrl_tbs(pemcrl, save)
PemCrl	 *pemcrl;
PE		 *save;
{
	(*save) = NULLPE;

	if( pemcrl->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSPemCrl(save,1,0,NULLCP,pemcrl->tbs) == NOTOK)
		return (NULLPE);
	    pemcrl->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(pemcrl->tbs_DERcode);

	return(*save);
}

%}

-- partially automatically generated by posy 5.0 #6 (Prag)!

--
--                Certificates and Related Types from:
--            X.509 The Directory - Authentication Framework
--                  Subset of Definitions in Annex G
--
--                PKRoot and PKList from SecureDFN Project

-- AuthenticationFramework
AF    DEFINITIONS ::=

%{	/* surrounding global definitions	*/
#include        "af.h"

static PE            build_revlist_tbs(), build_revcert_tbs(), build_tbs();
static PE 	     build_pemcrl_tbs();
PE                   aux_OctetString2PE();
struct type_IF_Name *aux_Name2DName();
char                *aux_DName2Name();
OctetString         *aux_PE2OctetString();
%}

BEGIN
-- EXPORTS
--              Validity, TBSCertificate, Certificate, Certificates,
--              ForwardCertificationPath, CrossCertificates, CrossCertificatePair,
--              TBSCrl, Crl, 
--              RevCert, TBSRevCert,
--              TBSPemCrl, PemCrl, RevCertPem,
--              RevCertSequence, OldCertificateList,
--              SerialSet, CrlSet, CrlPSE, PemCrlWithCerts
--
-- IMPORTS	
--		Name
--			FROM InformationFramework(IF)
--
--              UTCTime, BITSTRING, OctetString, INTEGER
--			FROM UNIV
--
--              AlgorithmIdentifier, KeyInfo
--                      FROM SecurityFramework(SEC)
--
-- functions symmetric for both parsing and building
SECTIONS build  parse none



Validity [[ P ToBeSigned * ]] ::=
        SEQUENCE {
            notBefore
                UTCTime
                [[s parm -> notbefore ]],

            notAfter
                UTCTime
                [[s parm -> notafter ]]
        }

PKRootValidity [[ P Serial * ]] ::=
        SEQUENCE {
            notBefore
                UTCTime
                [[s parm -> notbefore ]],

            notAfter
                UTCTime
                [[s parm -> notafter ]]
        }

ENCODER build

SerialNumbers [[ P SerialNumbers *]] ::=
	SEQUENCE {
                [0] INTEGER
                [[i parm->initial ]]
		DEFAULT 0 <<parm->initial != 0>>,

                [1] INTEGER
                [[i parm->actual ]]
	}


PKRoot [[P PKRoot *]] ::=
        SEQUENCE {
            cA
                IF.Name
                [[p parm -> ca ]],

            newkey
                RootKey
                [[p parm -> newkey ]],

            oldkey
                RootKey
                [[p parm -> oldkey ]]
                OPTIONAL <<parm -> oldkey>>
        }


RootKey [[P struct Serial *]] ::=
        SEQUENCE {
            version
		[0] INTEGER
                [[i parm->version ]]
                {
                    v1988(0)
                }
                DEFAULT v1988 <<parm->version != 0>>,

            serial
                INTEGER
                [[i parm->serial ]],

            key
                SEC.KeyInfo
                [[p parm->key ]],

            validity
                [1] PKRootValidity
                [[p parm ]]
		OPTIONAL <<parm->notbefore>>,

	    signAlgID
                [2] SEC.AlgorithmIdentifier
                [[p parm->sig->signAI ]]
		OPTIONAL <<parm->sig>>,

	    signBitString
		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
		OPTIONAL <<parm -> sig>>
        }


TBSCertificate [[P ToBeSigned *]] ::=
        SEQUENCE {
            version[0]
                INTEGER
                [[i parm -> version ]]
                {
                    v1988(0)
                }
                DEFAULT v1988 <<parm -> version != 0>>,

            serialNumber
                INTEGER
                [[i parm -> serialnumber ]],

            signature
                SEC.AlgorithmIdentifier
                [[p parm -> signatureAI ]],

            issuer
                IF.Name
                [[p parm -> issuer ]],

            validity
                Validity
                [[p parm ]],

            subject
                IF.Name
                [[p parm -> subject ]],

            subjectPublickeyInfo
                SEC.KeyInfo
                [[p parm -> subjectPK ]]
        }


Certificate [[P Certificate *]]
%{	PE	tbs;
%}
    ::= SEQUENCE { -- SIGNED
		-- TBSCertificate
		ANY
		[[ a (build_tbs(parm,&tbs)) ]]
		%{    pe_free(tbs);
		%} ,

                SEC.AlgorithmIdentifier
                [[p parm -> sig ->signAI ]],

		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]

        }


Certificates [[P Certificates *]] ::=
        SEQUENCE {
            certificate
                Certificate
                [[p parm -> usercertificate ]],

            certificationPath
                ForwardCertificationPath
                [[p parm -> forwardpath ]]
                OPTIONAL <<parm -> forwardpath>>
        }


ForwardCertificationPath [[P FCPath *]] ::=
        SEQUENCE OF
            <<; parm; parm = parm -> next_forwardpath>>
            CertificateSet
            [[p parm -> liste ]]


CertificateSet [[P SET_OF_Certificate *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            Certificate
            [[p parm -> element ]]


CertificatePair [[P CertificatePair *]] ::=
        SEQUENCE {
            forward
                [0] Certificate
                [[p parm -> forward ]]
		OPTIONAL <<parm -> forward>>,

            reverse
                [1] Certificate
                [[p parm -> reverse ]]
		OPTIONAL <<parm -> reverse>>
        }


CrossCertificatePair [[P SET_OF_CertificatePair *]] ::=
	SET OF
	    <<; parm; parm = parm -> next>>
	    CertificatePair
	    [[p parm -> element ]]


PKList [[P PKList *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            TBSCertificate
            [[p parm -> element ]]


TBSCrl [[ P CrlTBS *]]
    ::=     -- SIGNED type
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p parm->signatureAI ]],

            issuer
		IF.Name
		[[ p parm->issuer ]],

            lastUpdate
                UTCTime
		[[ s parm->lastupdate ]],

            revokedCertificates
		RevCertSequence
		[[ p parm->revokedcertificates ]]
		OPTIONAL <<parm->revokedcertificates>>
        }


Crl [[ P Crl *]]
    %{
	PE tbs;
    %}
    ::=
	SEQUENCE   -- SIGNED
	{       -- TBSCrl
                ANY
		[[ a (build_revlist_tbs(parm,&tbs)) ]]
		%{   pe_free(tbs);
		%},

                SEC.AlgorithmIdentifier
		[[ p parm->sig->signAI ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
	}  -- end of SIGNED


TBSRevCert [[ P RevCertTBS *]] ::=
	SEQUENCE  -- SIGNED type
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p parm->signatureAI ]],

            issuer
		IF.Name
		[[ p parm->issuer ]],

            subject
                INTEGER
		[[ i parm->subject ]],

	    revocationDate
                UTCTime
		[[ s parm->revocationdate ]]
        }


RevCert [[ P RevCert *]]
    %{
	PE tbs;
    %}
    ::=
	SEQUENCE   -- SIGNED
	{       -- TBSRevCert
                ANY
		[[ a (build_revcert_tbs(parm,&tbs)) ]]
		%{   pe_free(tbs);
		%},

                SEC.AlgorithmIdentifier
		[[ p parm->sig->signAI ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertSequence [[ P SEQUENCE_OF_RevCert *]]
    ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    RevCert
	    [[ p (parm->element) ]]


TBSPemCrl [[ P PemCrlTBS *]]
    ::=     -- SIGNED type
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p parm->signatureAI ]],

            issuer
		IF.Name
		[[ p parm->issuer ]],

            lastUpdate
                UTCTime
		[[ s parm->lastUpdate ]],

	    nextUpdate
                UTCTime
		[[ s parm->nextUpdate ]],

            revokedCertificates
		RevCertPemSequence
		[[ p parm->revokedCertificates ]]
		OPTIONAL <<parm->revokedCertificates>>
        }


PemCrl [[ P PemCrl *]]
    %{
	PE tbs;
    %}
    ::=
	SEQUENCE   -- SIGNED
	{       -- TBSCrl
                ANY
		[[ a (build_pemcrl_tbs(parm,&tbs)) ]]
		%{   pe_free(tbs);
		%},

                SEC.AlgorithmIdentifier
		[[ p parm->sig->signAI ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x parm->sig->signature.bits $
		     parm->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertPem [[ P RevCertPem *]] ::=
	SEQUENCE
        {
            serialNumber
                INTEGER
		[[ i parm->serialnumber ]],

	    revocationDate
                UTCTime
		[[ s parm->revocationDate ]]
        }


RevCertPemSequence [[ P SEQUENCE_OF_RevCertPem *]]
    ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    RevCertPem
	    [[ p (parm->element) ]]


SerialSet [[P SET_OF_int *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            INTEGER
            [[i parm -> element ]]


CrlPSE [[P CrlPSE *]] ::=
	SEQUENCE
        {
            issuer
		IF.Name
		[[ p parm->issuer ]],

            nextUpdate
                UTCTime
		[[ s parm->nextUpdate ]],

	    revcerts
		RevCertPemSequence
		[[ p parm->revcerts ]]
		OPTIONAL <<parm->revcerts>>
        }


CrlSet [[P CrlSet *]] ::=
        SET OF
            <<; parm; parm = parm -> next>>
            CrlPSE
            [[p parm -> element ]]


OldCertificateList [[ P OCList *]]
    ::=
        SEQUENCE OF
	    <<; parm; parm = parm->next>>
            SEQUENCE
            {
                serialNumber
                    INTEGER
		    [[ i parm->serialnumber ]],

                crossCertificate
                    AF.Certificate
		    [[ p parm->ccert ]]
            }


CertificationPath [[P CertificationPath *]] ::=
	SEQUENCE {
            userCertificate
                Certificate
                [[p parm->userCertificate ]],

            theCACertificates
                CertificatePairs
                [[p parm->theCACertificates ]]
		OPTIONAL <<parm->theCACertificates>>
        }


CertificatePairs [[ P CertificatePairs *]] 
%{
SEQUENCE_OF_CertificatePair * level;
%}
	::=
	SEQUENCE OF
		<<level = (parm)? parm->liste:(SEQUENCE_OF_CertificatePair * )0; 
		  level; 
		  level = (level->next)? level->next:((parm = parm->superior)? parm->liste:(SEQUENCE_OF_CertificatePair * )0)>>
		CertificatePair
		[[ p level->element ]]


PemCrlWithCerts [[P PemCrlWithCerts *]] ::=
	SEQUENCE {
            pemCRL
                PemCrl
                [[p parm->pemcrl ]],

            certificates
                Certificates
                [[p parm->certificates ]]
		OPTIONAL <<parm->certificates>>
        }


AliasesMember [[P Aliases *]] ::=
	SEQUENCE {
	    aname
		IA5String
		[[s parm->aname]],

	    aliasfile
		ENUMERATED
		[[i parm->aliasfile]]
		{
			useralias (0),
			sytemalias (1)
		}
	}


Aliases [[P Aliases *]] ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    AliasesMember
	    [[ p parm]]


AliasListMember [[P AliasList *]] ::=
	SEQUENCE {
	    aliases
		Aliases
		[[p parm->a]],

	    dname
		IA5String
		[[s parm->dname]]
	}


AliasList [[P AliasList *]] ::=
	SEQUENCE OF
	    <<; parm; parm = parm->next>>
	    AliasListMember
	    [[ p parm]]



DECODER parse


SerialNumbers [[ P SerialNumbers **]] ::=
    %{
        if ((*(parm) = (SerialNumbers *)
                calloc (1, sizeof **(parm))) == ((SerialNumbers *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm)->initial = 0;
    %}
        SEQUENCE {
                [0] INTEGER
                [[i (* parm)->initial ]]
		DEFAULT 0,

                [1] INTEGER
                [[i (* parm)->actual ]]
	}


PKRoot [[P PKRoot **]] ::=
    %{
        if ((*(parm) = (PKRoot *)
                calloc (1, sizeof **(parm))) == ((PKRoot *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE {
            cA
                IF.Name
                [[p &((*parm) -> ca)]],

            newkey
                RootKey
                [[p &((*parm) -> newkey)]],

            oldkey
                RootKey
                [[p &((*parm) -> oldkey)]]
                OPTIONAL
        }


RootKey [[P struct Serial **]] ::=
    %{
        if ((*(parm) = (struct Serial *)
                calloc (1, sizeof **(parm))) == ((struct Serial *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->key = (KeyInfo *)
                calloc (1, sizeof (KeyInfo))) == ((KeyInfo *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->sig = (Signature *)
                calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm)->notbefore = CNULL;
	(*parm)->notafter = CNULL;
	(*parm)->sig->signAI = NULLALGID;
	(*parm)->sig->signature.bits = CNULL;
	(*parm)->sig->signature.nbits = 0;
    %}
        SEQUENCE {
            version
		[0] INTEGER
                [[i (*parm)->version ]]
                {
                    v1988(0),v1992(1)
                }
                DEFAULT v1988,

            serial
                INTEGER
                [[i (*parm)->serial ]],

            key
                SEC.KeyInfo
                [[p ((*parm)->key)]],

            validity
                [1] PKRootValidity
                [[p (*parm) ]]
		OPTIONAL,

	    signAlgID
                [2] SEC.AlgorithmIdentifier
                [[p &((*parm)->sig->signAI) ]]
		OPTIONAL,

	    signBitString
		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
		OPTIONAL <<(*parm)->sig->signAI>>
        }
    %{
	if(! (*parm)->sig->signAI){
		aux_free_KeyInfo( (KeyInfo **) & ((*parm)->sig) );
		(*parm)->sig = (Signature * ) 0;
	}
    %}


TBSCertificate [[P ToBeSigned **]] ::=
    %{
        if ((*(parm) = (ToBeSigned *)
                calloc (1, sizeof **(parm))) == ((ToBeSigned *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->subjectPK = (KeyInfo *)
                calloc (1, sizeof (KeyInfo))) == ((KeyInfo *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm) -> version = 0;
    %}
        SEQUENCE {
            version[0]
                INTEGER
                [[i (*parm) -> version ]]
                {
                    v1988(0),v1992(1)
                }
                DEFAULT v1988,

            serialNumber
                INTEGER
                [[i (*parm) -> serialnumber ]],

            signature
                SEC.AlgorithmIdentifier
                [[p &((*parm) -> signatureAI)]],

            issuer
                IF.Name
                [[p &((*parm) -> issuer)]],

            validity
                Validity
                [[p (*parm) ]],

            subject
                IF.Name
                [[p &((*parm) -> subject)]],

            subjectPublickeyInfo
                SEC.KeyInfo
                [[p ((*parm) -> subjectPK)]]
        }


Certificate [[P Certificate **]] ::=
    %{
        if ((*(parm) = (Certificate *)
                calloc (1, sizeof **(parm))) == ((Certificate *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
        if (((*parm)->sig = (Signature *)
                calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE { -- SIGNED
		TBSCertificate
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %}   ,

                SEC.AlgorithmIdentifier
                [[p &((*parm) -> sig->signAI)]],

		-- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
        }


Certificates [[P Certificates **]] ::=
    %{
        if ((*(parm) = (Certificates *)
                calloc (1, sizeof **(parm))) == ((Certificates *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE {
            certificate
                Certificate
                [[p &((*parm) -> usercertificate)]],

            certificationPath
                ForwardCertificationPath
                [[p &((*parm) -> forwardpath)]]
                OPTIONAL
        }


ForwardCertificationPath [[P FCPath **]] ::=
        SEQUENCE OF
            %{
                if ((*(parm) = (FCPath *)
                        calloc (1, sizeof **(parm))) == ((FCPath *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            CertificateSet
            [[p &((*parm) -> liste)]]
            %{ parm = &((*parm) -> next_forwardpath); %}


CertificateSet [[P SET_OF_Certificate **]] ::=
        SET OF
            %{
                if ((*(parm) = (SET_OF_Certificate *)
                        calloc (1, sizeof **(parm))) == ((SET_OF_Certificate *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            Certificate
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


CertificatePair [[P CertificatePair **]] ::=
    %{
        if ((*(parm) = (CertificatePair *)
                calloc (1, sizeof **(parm))) == ((CertificatePair *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
    %}
        SEQUENCE {
            forward
                [0] Certificate
                [[p &((*parm) -> forward)]]
		OPTIONAL,

            reverse
                [1] Certificate
                [[p &((*parm) -> reverse)]]
		OPTIONAL
        }


CrossCertificatePair [[P SET_OF_CertificatePair **]] ::=
        SET OF
            %{
                if ((*(parm) = (SET_OF_CertificatePair *)
                        calloc (1, sizeof **(parm))) == ((SET_OF_CertificatePair *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            CertificatePair
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


PKList [[P PKList **]] ::=
        SET OF
            %{
                if ((*(parm) = (PKList *)
                        calloc (1, sizeof **(parm))) == ((PKList *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            TBSCertificate
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


TBSCrl [[ P CrlTBS **]]
    ::=  -- SIGNED type
        %{
            if ((*(parm) = (CrlTBS *)
                    calloc (1, sizeof **(parm))) == ((CrlTBS *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
	    (*parm)->revokedcertificates = (SEQUENCE_OF_RevCert *)0;
	%}	
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->signatureAI) ]],

            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            lastUpdate
                UTCTime
		[[ s ((*parm)->lastupdate) ]],

            revokedCertificates
		RevCertSequence
		[[ p &((*parm)->revokedcertificates) ]]
		OPTIONAL
        }


Crl [[ P Crl **]] ::=
        %{
            if ((*(parm) = (Crl *)
                    calloc (1, sizeof **(parm))) == ((Crl *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
            if (((*parm)->sig = (Signature *)
                    calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}
	SEQUENCE  --SIGNED
        {
		TBSCrl
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if ( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %},
	   
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->sig->signAI) ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
	}  -- end of SIGNED


TBSRevCert [[ P RevCertTBS **]]
    ::=  -- SIGNED type
       %{
            if ((*(parm) = (RevCertTBS *)
                    calloc (1, sizeof **(parm))) == ((RevCertTBS *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
	%}
	SEQUENCE 
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->signatureAI) ]],

            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            subject
                INTEGER
		[[ i (*parm)->subject ]],

	    revocationDate
                UTCTime
		[[ s ((*parm)->revocationdate) ]]
        }


RevCert [[ P RevCert **]] ::=
        %{
            if ((*(parm) = (RevCert *)
                    calloc (1, sizeof **(parm))) == ((RevCert *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
            if (((*parm)->sig = (Signature *)
                    calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}
	SEQUENCE  -- SIGNED
        {
		TBSRevCert
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if ( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %},

                SEC.AlgorithmIdentifier
		[[ p &((*parm)->sig->signAI) ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertSequence [[ P SEQUENCE_OF_RevCert **]]
    ::=
        SEQUENCE OF
            %{
		if ((*(parm) = (SEQUENCE_OF_RevCert *)
			calloc (1, sizeof **(parm))) == (SEQUENCE_OF_RevCert *) 0) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
		(*parm) -> next = (SEQUENCE_OF_RevCert *)0;
            %}
	    RevCert
	    [[ p &((*parm) -> element) ]]
            %{ parm = &((*parm) -> next); %}


TBSPemCrl [[ P PemCrlTBS **]]
    ::=  -- SIGNED type
        %{
            if ((*(parm) = (PemCrlTBS *)
                    calloc (1, sizeof **(parm))) == ((PemCrlTBS *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
	    (*parm)->revokedCertificates = (SEQUENCE_OF_RevCertPem *)0;
	%}	
        SEQUENCE
        {
            signature
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->signatureAI) ]],

            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            lastUpdate
                UTCTime
		[[ s ((*parm)->lastUpdate) ]],

            nextUpdate
                UTCTime
		[[ s ((*parm)->nextUpdate) ]],

            revokedCertificates
		RevCertPemSequence
		[[ p &((*parm)->revokedCertificates) ]]
		OPTIONAL
        }


PemCrl [[ P PemCrl **]] ::=
        %{
            if ((*(parm) = (PemCrl *)
                    calloc (1, sizeof **(parm))) == ((PemCrl *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
            if (((*parm)->sig = (Signature *)
                    calloc (1, sizeof (Signature))) == ((Signature *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}
	SEQUENCE  --SIGNED
        {
		TBSPemCrl
		[[ p &((*parm)->tbs) ]]
	   %{ /* set x509_tbs */
		(*parm)->tbs_DERcode = aux_PE2OctetString($$);
		if ( (*parm)->tbs_DERcode == (OctetString *)0 ) return NOTOK;
	   %},
	   
                SEC.AlgorithmIdentifier
		[[ p &((*parm)->sig->signAI) ]],

	   -- ENCRYPTED OCTET STRING -- BITSTRING
		[[ x (*parm)->sig->signature.bits $
		     (*parm)->sig->signature.nbits ]]
	}  -- end of SIGNED


RevCertPemSequence [[ P SEQUENCE_OF_RevCertPem **]]
    ::=
        SEQUENCE OF
            %{
		if ((*(parm) = (SEQUENCE_OF_RevCertPem *)
			calloc (1, sizeof **(parm))) == (SEQUENCE_OF_RevCertPem *) 0) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
		(*parm) -> next = (SEQUENCE_OF_RevCertPem *)0;
            %}
	    RevCertPem
	    [[ p &((*parm) -> element) ]]
            %{ parm = &((*parm) -> next); %}


RevCertPem [[ P RevCertPem **]]
    ::= 
        %{
            if ((*(parm) = (RevCertPem *)
                    calloc (1, sizeof **(parm))) == ((RevCertPem *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}  
	SEQUENCE 
        {
            serialNumber
                INTEGER
		[[ i (*parm)->serialnumber ]],

	    revocationDate
                UTCTime
		[[ s (*parm)->revocationDate ]]
        }


SerialSet [[P SET_OF_int **]] ::=
        SET OF
            %{
                if ((*(parm) = (SET_OF_int *)
                        calloc (1, sizeof **(parm))) == ((SET_OF_int *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            INTEGER
            [[i (*parm) -> element ]]
            %{ parm = &((*parm) -> next); %}


CrlPSE [[ P CrlPSE **]]
    ::= 
        %{
            if ((*(parm) = (CrlPSE *)
                    calloc (1, sizeof **(parm))) == ((CrlPSE *) 0)) {
                advise (NULLCP, "out of memory");
                return NOTOK;
            }
        %}  
	SEQUENCE 
        {
            issuer
		IF.Name
		[[ p &((*parm)->issuer) ]],

            nextUpdate
                UTCTime
		[[ s ((*parm)->nextUpdate) ]],

            revcerts
		RevCertPemSequence
		[[ p &((*parm)->revcerts) ]]
		OPTIONAL
        }


CrlSet [[P CrlSet **]] ::=
        SET OF
            %{
                if ((*(parm) = (CrlSet *)
                        calloc (1, sizeof **(parm))) == ((CrlSet *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
            CrlPSE
            [[p &((*parm) -> element)]]
            %{ parm = &((*parm) -> next); %}


OldCertificateList [[ P OCList **]]
    ::=
        SEQUENCE OF
            %{
		if ((*(parm) = (OCList *)
			calloc (1, sizeof **(parm))) == (OCList *) 0) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
		(*parm) -> next = (OCList *)0;
            %}
            SEQUENCE
            {
                serialNumber
                    INTEGER
		    [[ i (*parm) -> serialnumber ]],

                crossCertificate
                    AF.Certificate
		    [[ p &((*parm) -> ccert) ]]
            }
            %{ parm = &((*parm) -> next); %}


PemCrlWithCerts [[P PemCrlWithCerts **]] ::=
    %{
        if ((*(parm) = (PemCrlWithCerts *)
                calloc (1, sizeof **(parm))) == ((PemCrlWithCerts *) 0)) {
            advise (NULLCP, "out of memory");
            return NOTOK;
        }
	(*parm)->certificates = (Certificates * )0;
    %}
        SEQUENCE {
            pemCRL
                PemCrl
                [[p &((*parm) -> pemcrl)]],

            certificates
                Certificates
                [[p &((*parm) -> certificates)]]
                OPTIONAL
        }


AliasesMember [[P Aliases *]] ::=
	SEQUENCE {
	    aname
		IA5String
		[[s parm->aname]],

	    aliasfile
		ENUMERATED
		[[i parm->aliasfile]]
		{
			useralias (0),
			systemalias (1)
		}
	}


Aliases [[P Aliases **]] ::=
	SEQUENCE OF
            %{
                if ((*(parm) = (Aliases *)
                        calloc (1, sizeof **(parm))) == ((Aliases *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
	    AliasesMember
	    [[ p *parm]]
            %{ parm = &((*parm) -> next); %}


AliasListMember [[P AliasList *]] ::=
	SEQUENCE {
	    aliases
		Aliases
		[[p &(parm->a)]],

	    dname
		IA5String
		[[s parm->dname]]
	}


AliasList [[P AliasList **]] ::=
	SEQUENCE OF
            %{
                if ((*(parm) = (AliasList *)
                        calloc (1, sizeof **(parm))) == ((AliasList *) 0)) {
                    advise (NULLCP, "out of memory");
                    return NOTOK;
                }
            %}
	    AliasListMember
	    [[ p *parm]]
            %{ parm = &((*parm) -> next); %}


END


%{
/************************ local functions: ****/

static
PE	build_tbs(cert,save)
Certificate      *cert;
PE               *save;
{
	(*save) = NULLPE;

	if( cert->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSCertificate(save,1,0,NULLCP, cert->tbs) == NOTOK)
		return NULLPE;
	    cert->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(cert->tbs_DERcode);

	return(*save);
}

static
PE      build_revlist_tbs(revlist,save)
Crl   *revlist;
PE        *save;
{
	(*save) = NULLPE;

	if( revlist->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSCrl(save,1,0,NULLCP,revlist->tbs) == NOTOK)
		return (NULLPE);
	    revlist->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(revlist->tbs_DERcode);

	return(*save);
}

static
PE      build_revcert_tbs(revcert,save)
RevCert      *revcert;
PE           *save;
{
	(*save) = NULLPE;

	if( revcert->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSRevCert(save,1,0,NULLCP,revcert->tbs) == NOTOK)
		return (NULLPE);
	    revcert->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(revcert->tbs_DERcode);

	return(*save);
}

static
PE	build_pemcrl_tbs(pemcrl, save)
PemCrl	 *pemcrl;
PE		 *save;
{
	(*save) = NULLPE;

	if( pemcrl->tbs_DERcode == (OctetString *)0 )
	{
	    if (build_AF_TBSPemCrl(save,1,0,NULLCP,pemcrl->tbs) == NOTOK)
		return (NULLPE);
	    pemcrl->tbs_DERcode = aux_PE2OctetString(*save);
	}
	else   (*save) = aux_OctetString2PE(pemcrl->tbs_DERcode);

	return(*save);
}

%}

#6 (Prag)! #include        "af.h"