/* -*- Mode: C; tab-width: 8 -*-*/
/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is the Netscape security libraries.
 * 
 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are 
 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 * Rights Reserved.
 * 
 * Contributor(s):
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL"), in which case the provisions of the GPL are applicable 
 * instead of those above.  If you wish to allow use of your 
 * version of this file only under the terms of the GPL and not to
 * allow others to use your version of this file under the MPL,
 * indicate your decision by deleting the provisions above and
 * replace them with the notice and other provisions required by
 * the GPL.  If you do not delete the provisions above, a recipient
 * may use your version of this file under either the MPL or the
 * GPL.
 */

#ifndef _CMMF_H_
#define _CMMF_H_
/*
 * These are the functions exported by the security library for 
 * implementing Certificate Management Message Formats (CMMF).
 *
 * This API is designed against July 1998 CMMF draft.  Please read this
 * draft before trying to use this API in an application that use CMMF.
 */
#include "seccomon.h"
#include "cmmft.h"
#include "crmf.h"

SEC_BEGIN_PROTOS

/******************* Creation Functions *************************/

/*
 * FUNCTION: CMMF_CreateCertRepContent
 * INPUTS:
 *    NONE
 * NOTES:
 *    This function will create an empty CMMFCertRepContent Structure.  
 *    The client of the library must set the CMMFCertResponses.
 *    Call CMMF_CertRepContentSetCertResponse to accomplish this task.
 *    If the client of the library also wants to include the chain of 
 *    CA certs required to make the certificates in CMMFCertResponse valid, 
 *    then the user must also set the caPubs field of CMMFCertRepContent.
 *    Call CMMF_CertRepContentSetCAPubs to accomplish this.  After setting
 *    the desired fields, the user can then call CMMF_EncodeCertRepContent 
 *    to DER-encode the CertRepContent.
 * RETURN:
 *    A pointer to the CMMFCertRepContent.  A NULL return value indicates 
 *    an error in allocating memory or failure to initialize the structure.
 */
extern CMMFCertRepContent* CMMF_CreateCertRepContent(void);

/*
 * FUNCTION: CMMF_CreateCertRepContentFromDER
 * INPUTS
 *    db
 *        The certificate database where the certificates will be placed.
 *        The certificates will be placed in the temporary database associated
 *        with the handle. 
 *    buf
 *        A buffer to the DER-encoded CMMFCertRepContent
 *    len
 *        The length in bytes of the buffer 'buf'
 * NOTES:
 *    This function passes the buffer to the ASN1 decoder and creates a
 *    CMMFCertRepContent structure.  The user must call 
 *    CMMF_DestroyCertRepContent after the return value is no longer needed.
 *
 * RETURN:
 *    A pointer to the CMMFCertRepContent structure.  A NULL return
 *    value indicates the library was unable to parse the DER.
 */
extern CMMFCertRepContent* 
       CMMF_CreateCertRepContentFromDER(CERTCertDBHandle *db, 
					const char       *buf, 
					long              len);

/*
 * FUNCTION: CMMF_CreateCertResponse
 * INPUTS:
 *    inCertReqId
 *        The Certificate Request Id this response is for.
 * NOTES:
 *    This creates a CMMFCertResponse.  This response should correspond
 *    to a request that was received via CRMF.  From the CRMF message you
 *    can get the Request Id to pass in as inCertReqId, in essence binding 
 *    a CMRFCertRequest message to the CMMFCertResponse created by this
 *    function.  If no requuest id is associated with the response to create
 *    then the user should pass in -1 for 'inCertReqId'.
 *
 * RETURN:
 *    A pointer to the new CMMFCertResponse corresponding to the request id 
 *    passed in.  A NULL return value indicates an error while trying to 
 *    create the CMMFCertResponse.
 */
extern CMMFCertResponse* CMMF_CreateCertResponse(long inCertReqId);

/*
 * FUNCTION: CMMF_CreateKeyRecRepContent
 * INPUTS:
 *    NONE
 * NOTES:
 *    This function creates a new empty CMMFKeyRecRepContent structure.
 *    At the very minimum, the user  must call 
 *    CMMF_KeyRecRepContentSetPKIStatusInfoStatus field to have an
 *    encodable structure.  Depending on what the response is, the user may
 *    have to set other fields as well to properly build up the structure so
 *    that it can be encoded.  Refer to the CMMF draft for how to properly
 *    set up a CMMFKeyRecRepContent. This is the structure that an RA returns
 *    to an end entity when doing key recovery.

 *    The user must call CMMF_DestroyKeyRecRepContent when the return value
 *    is no longer needed.
 * RETURN:
 *    A pointer to the empty CMMFKeyRecRepContent.  A return value of NULL
 *    indicates an error in allocating memory or initializing the structure.
 */
extern CMMFKeyRecRepContent *CMMF_CreateKeyRecRepContent(void);

/*
 * FUNCTION: CMMF_CreateKeyRecRepContentFromDER
 * INPUTS:
 *    db
 *        The handle for the certificate database where the decoded 
 *        certificates will be placed.  The decoded certificates will
 *        be placed in the temporary database associated with the 
 *        handle.
 *    buf
 *        A buffer contatining the DER-encoded CMMFKeyRecRepContent
 *    len
 *        The length in bytes of the buffer 'buf'
 * NOTES
 *    This function passes the buffer to the ASN1 decoder and creates a 
 *    CMMFKeyRecRepContent structure.
 *
 * RETURN:
 *    A pointer to the CMMFKeyRecRepContent structure.  A NULL return
 *    value indicates the library was unable to parse the DER.
 */
extern CMMFKeyRecRepContent* 
       CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db,
					  const char       *buf,
					  long              len);

/*
 * FUNCTION: CMMF_CreatePOPODecKeyChallContent
 * INPUTS:
 *    NONE
 * NOTES:
 *    This function creates an empty CMMFPOPODecKeyChallContent.  The user
 *    must add the challenges individually specifying the random number to
 *    be used and the public key to be used when creating each individual 
 *    challenge.  User can accomplish this by calling the function 
 *    CMMF_POPODecKeyChallContentSetNextChallenge.
 * RETURN:
 *    A pointer to a CMMFPOPODecKeyChallContent structure.  Ther user can
 *    then call CMMF_EncodePOPODecKeyChallContent passing in the return
 *    value from this function after setting all of the challenges.  A 
 *    return value of NULL indicates an error while creating the 
 *    CMMFPOPODecKeyChallContent structure.
 */
extern CMMFPOPODecKeyChallContent*
       CMMF_CreatePOPODecKeyChallContent(void);

/*
 * FUNCTION: CMMF_CreatePOPODecKeyChallContentFromDER
 * INPUTS
 *    buf
 *        A buffer containing the DER-encoded CMMFPOPODecKeyChallContent
 *    len
 *        The length in bytes of the buffer 'buf'
 * NOTES:
 *    This function passes the buffer to the ASN1 decoder and creates a
 *    CMMFPOPODecKeyChallContent structure.  
 *
 * RETURN:
 *    A pointer to the CMMFPOPODecKeyChallContent structure.  A NULL return
 *    value indicates the library was unable to parse the DER.
 */
extern CMMFPOPODecKeyChallContent*
       CMMF_CreatePOPODecKeyChallContentFromDER(const char *buf, long len);

/*
 * FUNCTION: CMMF_CreatePOPODecKeyRespContentFromDER
 * INPUTS:
 *    buf
 *        A buffer contatining the DER-encoded CMMFPOPODecKeyRespContent
 *    len
 *        The length in bytes of the buffer 'buf'
 * NOTES
 *    This function passes the buffer to the ASN1 decoder and creates a 
 *    CMMFPOPODecKeyRespContent structure.
 *
 * RETURN:
 *    A pointer to the CMMFPOPODecKeyRespContent structure.  A NULL return
 *    value indicates the library was unable to parse the DER.
 */
extern CMMFPOPODecKeyRespContent*
       CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len);

/************************** Set Functions *************************/

/*
 * FUNCTION: CMMF_CertRepContentSetCertResponses
 * INPUTS:
 *    inCertRepContent
 *        The CMMFCertRepContent to operate on.
 *    inCertResponses
 *        An array of pointers to CMMFCertResponse structures to 
 *        add to the CMMFCertRepContent structure.
 *    inNumResponses
 *        The length of the array 'inCertResponses'
 * NOTES:
 *    This function will add the CMMFCertResponse structure to the 
 *    CMMFCertRepContent passed in.  The CMMFCertResponse field of 
 *    CMMFCertRepContent is required, so the client must call this function
 *    before calling CMMF_EncodeCertRepContent.  If the user calls 
 *    CMMF_EncodeCertRepContent before calling this function, 
 *    CMMF_EncodeCertRepContent will fail.
 *
 * RETURN:
 *    SECSuccess if adding the CMMFCertResponses to the CMMFCertRepContent
 *    structure was successful.  Any other return value indicates an error
 *    while trying to add the CMMFCertResponses.
 */
extern SECStatus 
      CMMF_CertRepContentSetCertResponses(CMMFCertRepContent *inCertRepContent,
					  CMMFCertResponse  **inCertResponses,
					  int                 inNumResponses);

/*
 * FUNCTION: CMMF_CertRepContentSetCAPubs
 * INPUTS:
 *    inCertRepContent
 *        The CMMFCertRepContent to operate on.
 *    inCAPubs
 *        The certificate list which makes up the chain of CA certificates
 *        required to make the issued cert valid.
 * NOTES:
 *    This function will set the the certificates in the CA chain as part
 *    of the CMMFCertRepContent.  This field is an optional member of the 
 *    CMMFCertRepContent structure, so the client is not required to call
 *    this function before calling CMMF_EncodeCertRepContent.
 *
 * RETURN:
 *    SECSuccess if adding the 'inCAPubs' to the CERTRepContent was successful.
 *    Any other return value indicates an error while adding 'inCAPubs' to the 
 *    CMMFCertRepContent structure.
 * 
 */
extern SECStatus 
       CMMF_CertRepContentSetCAPubs (CMMFCertRepContent  *inCertRepContent,
				     CERTCertList        *inCAPubs);

/*
 * FUNCTION: CMMF_CertResponseSetPKIStatusInfoStatus
 * INPUTS:
 *    inCertResp
 *        The CMMFCertResponse to operate on.
 *     inPKIStatus
 *        The value to set for the PKIStatusInfo.status field.
 * NOTES:
 *    This function will set the CertResponse.status.status field of 
 *    the CMMFCertResponse structure.  (View the definition of CertResponse
 *    in the CMMF draft to see exactly which value this talks about.)  This
 *    field is a required member of the structure, so the user must call this
 *    function in order to have a CMMFCertResponse that can be encoded.
 *
 * RETURN:
 *    SECSuccess if setting the field with the passed in value was successful.
 *    Any other return value indicates an error while trying to set the field.
 */
extern SECStatus 
     CMMF_CertResponseSetPKIStatusInfoStatus (CMMFCertResponse *inCertResp,
					      CMMFPKIStatus     inPKIStatus);

/*
 * FUNCTION: CMMF_CertResponseSetCertificate
 * INPUTS:
 *    inCertResp
 *        The CMMFCertResponse to operate on.
 *    inCertificate
 *        The certificate to add to the 
 *        CertResponse.CertifiedKeyPair.certOrEncCert.certificate field.
 * NOTES:
 *    This function will take the certificate and make it a member of the
 *    CMMFCertResponse.  The certificate should be the actual certificate
 *    being issued via the response.
 *
 * RETURN:
 *    SECSuccess if adding the certificate to the response was successful.
 *    Any other return value indicates an error in adding the certificate to
 *    the CertResponse.
 */
extern SECStatus 
       CMMF_CertResponseSetCertificate (CMMFCertResponse *inCertResp,
					CERTCertificate  *inCertificate);

/*
 * FUNCTION: CMMF_KeyRecRepContentSetPKIStatusInfoStatus
 * INPUTS: 
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to operate on.
 *    inPKIStatus
 *        The value to set the PKIStatusInfo.status field to.
 * NOTES:
 *    This function sets the only required field for the KeyRecRepContent.
 *    In most cases, the user will set this field and other fields of the
 *    structure to properly create the CMMFKeyRecRepContent structure.  
 *    Refer to the CMMF draft to see which fields need to be set in order
 *    to create the desired CMMFKeyRecRepContent.
 * 
 * RETURN:
 *    SECSuccess if setting the PKIStatusInfo.status field was successful.
 *    Any other return value indicates an error in setting the field.
 */
extern SECStatus 
CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
					    CMMFPKIStatus         inPKIStatus);

/*
 * FUNCTION: CMMF_KeyRecRepContentSetNewSignCert
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to operate on.
 *    inNewSignCert
 *        The new signing cert to add to the CMMFKeyRecRepContent structure.
 * NOTES:
 *    This function sets the new signeing cert in the CMMFKeyRecRepContent
 *    structure.
 *
 * RETURN:
 *    SECSuccess if setting the new signing cert was successful.  Any other 
 *    return value indicates an error occurred while trying to add the
 *    new signing certificate.
 */
extern SECStatus 
       CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
					   CERTCertificate     *inNewSignCert);

/*
 * FUNCTION: CMMF_KeyRecRepContentSetCACerts
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to operate on.
 *    inCACerts
 *        The list of CA certificates required to construct a valid 
 *        certificate chain with the certificates that will be returned
 *        to the end user via this KeyRecRepContent.
 * NOTES:
 *    This function sets the caCerts that are required to form a chain with the
 *    end entity certificates that are being re-issued in this 
 *    CMMFKeyRecRepContent structure.
 *
 * RETURN:
 *    SECSuccess if adding the caCerts was successful.  Any other return value
 *    indicates an error while tring to add the caCerts.
 */
extern SECStatus 
       CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
				       CERTCertList         *inCACerts);

/*
 * FUNCTION: CMMF_KeyRecRepContentSetCertifiedKeyPair
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to operate on.
 *    inCert
 *        The certificate to add to the CMMFKeyRecRepContent structure.
 *    inPrivKey
 *        The private key associated with the certificate above passed in.
 *    inPubKey
 *        The public key to use for wrapping the private key.
 * NOTES:
 *    This function adds another certificate-key pair to the 
 *    CMMFKeyRecRepcontent structure.  There may be more than one 
 *    certificate-key pair in the structure, so the user must call this 
 *    function multiple times to add more than one cert-key pair.
 *
 * RETURN:
 *    SECSuccess if adding the certified key pair was successful.  Any other
 *    return value indicates an error in adding certified key pair to 
 *    CMMFKeyRecRepContent structure.
 */
extern SECStatus 
    CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
					     CERTCertificate      *inCert,
					     SECKEYPrivateKey     *inPrivKey,
					     SECKEYPublicKey      *inPubKey);

/*
 * FUNCTION: CMMF_POPODecKeyChallContentSetNextChallenge
 * INPUTS:
 *    inDecKeyChall
 *        The CMMFPOPODecKeyChallContent to operate on.
 *    inRandom
 *        The random number to use when generating the challenge,
 *    inSender
 *        The GeneralName representation of the sender of the challenge.
 *    inPubKey
 *        The public key to use when encrypting the challenge.
 *    passwdArg
 *        This value will be passed to the function used for getting a
 *        password.  The password for getting a password should be registered
 *        by calling PK11_SetPasswordFunc before this function is called. 
 *        If no password callback is registered and the library needs to 
 *        authenticate to the slot for any reason, this function will fail.
 * NOTES:
 *    This function adds a challenge to the end of the list of challenges
 *    contained by 'inDecKeyChall'.  Refer to the CMMF draft on how the
 *    the random number passed in and the sender's GeneralName are used
 *    to generate the challenge and witness fields of the challenge.  This
 *    library will use SHA1 as the one-way function for generating the 
 *    witess field of the challenge.
 *
 * RETURN:
 *    SECSuccess if generating the challenge and adding to the end of list
 *    of challenges was successful.  Any other return value indicates an error
 *    while trying to generate the challenge.
 */
extern SECStatus
CMMF_POPODecKeyChallContentSetNextChallenge
                                   (CMMFPOPODecKeyChallContent *inDecKeyChall,
				    long                        inRandom,
				    CERTGeneralName            *inSender,
				    SECKEYPublicKey            *inPubKey,
				    void                       *passwdArg);


/************************** Encoding Functions *************************/

/*
 * FUNCTION: CMMF_EncodeCertRepContent
 * INPUTS:
 *    inCertRepContent
 *        The CMMFCertRepContent to DER-encode.
 *    inCallback
 *        A callback function that the ASN1 encoder will call whenever it 
 *        wants to write out DER-encoded bytes.  Look at the defintion of 
 *        CRMFEncoderOutputCallback in crmft.h for a description of the
 *        parameters to the function.
 *    inArg
 *        An opaque pointer to a user-supplied argument that will be passed
 *        to the callback funtion whenever the function is called.
 * NOTES:
 *    The CMMF library will use the same DER-encoding scheme as the CRMF 
 *    library.  In other words, when reading CRMF comments that pertain to
 *    encoding, those comments apply to the CMMF libray as well.  
 *    The callback function will be called multiple times, each time supplying
 *    the next chunk of DER-encoded bytes.  The user must concatenate the 
 *    output of each successive call to the callback in order to get the
 *    entire DER-encoded CMMFCertRepContent structure.
 *
 * RETURN:
 *    SECSuccess if encoding the CMMFCertRepContent was successful.  Any 
 *    other return value indicates an error while decoding the structure.
 */
extern SECStatus 
       CMMF_EncodeCertRepContent (CMMFCertRepContent        *inCertRepContent,
				  CRMFEncoderOutputCallback  inCallback,
				  void                      *inArg);

/*
 * FUNCTION: CMMF_EncodeKeyRecRepContent
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRepContent to DER-encode.
 *    inCallback
 *        A callback function that the ASN1 encoder will call whenever it 
 *        wants to write out DER-encoded bytes.  Look at the defintion of 
 *        CRMFEncoderOutputCallback in crmft.h for a description of the
 *        parameters to the function.
 *    inArg
 *        An opaque pointer to a user-supplied argument that will be passed
 *        to the callback funtion whenever the function is called.
 * NOTES:
 *    The CMMF library will use the same DER-encoding scheme as the CRMF 
 *    library.  In other words, when reading CRMF comments that pertain to
 *    encoding, those comments apply to the CMMF libray as well.  
 *    The callback function will be called multiple times, each time supplying
 *    the next chunk of DER-encoded bytes.  The user must concatenate the 
 *    output of each successive call to the callback in order to get the
 *    entire DER-encoded CMMFCertRepContent structure.
 *
 * RETURN:
 *    SECSuccess if encoding the CMMFKeyRecRepContent was successful.  Any 
 *    other return value indicates an error while decoding the structure.
 */
extern SECStatus
       CMMF_EncodeKeyRecRepContent(CMMFKeyRecRepContent      *inKeyRecRep,
				   CRMFEncoderOutputCallback  inCallback,
				   void                      *inArg);

/*
 * FUNCTION: CMMF_EncodePOPODecKeyChallContent
 * INPUTS:
 *    inDecKeyChall
 *        The CMMFDecKeyChallContent to operate on.
 *    inCallback
 *        A callback function that the ASN1 encoder will call whenever it 
 *        wants to write out DER-encoded bytes.  Look at the defintion of 
 *        CRMFEncoderOutputCallback in crmft.h for a description of the
 *        parameters to the function.
 *    inArg
 *        An opaque pointer to a user-supplied argument that will be passed
 *        to the callback function whenever the function is called.
 * NOTES:
 *    The CMMF library will use the same DER-encoding scheme as the CRMF 
 *    library.  In other words, when reading CRMF comments that pertain to
 *    encoding, those comments apply to the CMMF libray as well.  
 *    The callback function will be called multiple times, each time supplying
 *    the next chunk of DER-encoded bytes.  The user must concatenate the 
 *    output of each successive call to the callback in order to get the
 *    entire DER-encoded CMMFCertRepContent structure.
 *    The DER will be an encoding of the type POPODecKeyChallContents, which
 *    is just a sequence of challenges.
 *
 * RETURN:
 *    SECSuccess if encoding was successful.  Any other return value indicates
 *    an error in trying to encode the Challenges.
 */
extern SECStatus 
CMMF_EncodePOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyChall,
				  CRMFEncoderOutputCallback inCallback,
				  void                     *inArg);

/*
 * FUNCTION: CMMF_EncodePOPODecKeyRespContent
 * INPUTS:
 *    inDecodedRand
 *        An array of integers to encode as the responses to 
 *        CMMFPOPODecKeyChallContent.  The integers must be in the same order
 *        as the challenges extracted from CMMFPOPODecKeyChallContent.
 *    inNumRand
 *        The number of random integers contained in the array 'inDecodedRand'
 *    inCallback
 *        A callback function that the ASN1 encoder will call whenever it 
 *        wants to write out DER-encoded bytes.  Look at the defintion of 
 *        CRMFEncoderOutputCallback in crmft.h for a description of the
 *        parameters to the function.
 *    inArg
 *        An opaque pointer to a user-supplied argument that will be passed
 *        to the callback funtion whenever the function is called.
 * NOTES:
 *    The CMMF library will use the same DER-encoding scheme as the CRMF 
 *    library.  In other words, when reading CRMF comments that pertain to
 *    encoding, those comments apply to the CMMF libray as well.  
 *    The callback function will be called multiple times, each time supplying
 *    the next chunk of DER-encoded bytes.  The user must concatenate the 
 *    output of each successive call to the callback in order to get the
 *    entire DER-encoded  POPODecKeyRespContent.
 *
 * RETURN:
 *    SECSuccess if encoding was successful.  Any other return value indicates
 *    an error in trying to encode the Challenges.
 */
extern SECStatus 
      CMMF_EncodePOPODecKeyRespContent(long                     *inDecodedRand,
				       int                       inNumRand,
				       CRMFEncoderOutputCallback inCallback,
				       void                     *inArg); 

/***************  Accessor function  ***********************************/

/*
 * FUNCTION: CMMF_CertRepContentGetCAPubs
 * INPUTS:
 *    inCertRepContent
 *        The CMMFCertRepContent to extract the caPubs from.
 * NOTES:
 *    This function will return a copy of the list of certificates that
 *    make up the chain of CA's required to make the cert issued valid.
 *    The user must call CERT_DestroyCertList on the return value when 
 *    done using the return value.  
 *
 *    Only call this function on a CertRepContent that has been decoded.
 *    The client must call CERT_DestroyCertList when the certificate list
 *    is no longer needed. 
 *
 *    The certs in the list will not be in the temporary database.  In order
 *    to make these certificates a part of the permanent CA internal database,
 *    the user must collect the der for all of these certs and call 
 *    CERT_ImportCAChain.  Afterwards the certs will be part of the permanent
 *    database.
 *    
 * RETURN:
 *    A pointer to the CERTCertList representing the CA chain associated 
 *    with the issued cert.  A NULL return value indicates  that no CA Pubs
 *    were available in the CMMFCertRepContent structure. 
 */
extern CERTCertList* 
       CMMF_CertRepContentGetCAPubs (CMMFCertRepContent *inCertRepContent);


/*
 * FUNCTION: CMMF_CertRepContentGetNumResponses
 * INPUTS:
 *    inCertRepContent
 *        The CMMFCertRepContent to operate on.
 * NOTES:
 *    This function will return the number of CertResponses that are contained
 *    by the CMMFCertRepContent passed in.
 * 
 * RETURN:
 *    The number of CMMFCertResponses contained in the structure passed in.
 */
extern int 
 CMMF_CertRepContentGetNumResponses (CMMFCertRepContent *inCertRepContent);

/*
 * FUNCTION: CMMF_CertRepContentGetResponseAtIndex
 * INPUTS:
 *    inCertRepContent
 *        The CMMFCertRepContent to operate on.
 *    inIndex
 *        The index of the CMMFCertResponse the user wants a copy of.
 * NOTES:
 *    This funciton creates a copy of the CMMFCertResponse at the index 
 *    corresponding to the parameter 'inIndex'.  Indexing is done like a
 *    traditional C array, ie the valid indexes are (0...numResponses-1).
 *    The user must call CMMF_DestroyCertResponse after the return value is 
 *    no longer needed.
 *
 * RETURN:
 *    A pointer to the CMMFCertResponse at the index corresponding to 
 *    'inIndex'.  A return value of NULL indicates an error in copying 
 *    the CMMFCertResponse.
 */
extern CMMFCertResponse*
CMMF_CertRepContentGetResponseAtIndex (CMMFCertRepContent *inCertRepContent,
				       int                 inIndex);

/*
 * FUNCTION: CMMF_CertResponseGetCertReqId
 * INPUTS:
 *    inCertResp
 *        The CMMFCertResponse to operate on.
 * NOTES:
 *    This function returns the CertResponse.certReqId from the 
 *    CMMFCertResponse structure passed in.  If the return value is -1, that
 *    means there is no associated certificate request with the CertResponse.
 * RETURN:
 *    A long representing the id of the certificate request this 
 *    CMMFCertResponse corresponds to.  A return value of -1 indicates an
 *    error in extracting the value of the integer.
 */
extern long CMMF_CertResponseGetCertReqId(CMMFCertResponse *inCertResp);

/*
 * FUNCTION: CMMF_CertResponseGetPKIStatusInfoStatus
 * INPUTS:
 *    inCertResp
 *        The CMMFCertResponse to operate on.
 * NOTES:
 *    This function returns the CertResponse.status.status field of the 
 *    CMMFCertResponse structure.
 *
 * RETURN:
 *    The enumerated value corresponding to the PKIStatus defined in the CMMF
 *    draft.  See the CMMF draft for the definition of PKIStatus.  See crmft.h
 *    for the definition of CMMFPKIStatus.
 */
extern CMMFPKIStatus 
       CMMF_CertResponseGetPKIStatusInfoStatus(CMMFCertResponse *inCertResp);

/*
 * FUNCTION: CMMF_CertResponseGetCertificate
 * INPUTS:
 *    inCertResp
 *        The Certificate Response to operate on.
 *    inCertdb
 *        This is the certificate database where the function will place the
 *        newly issued certificate.
 * NOTES:
 *    This function retrieves the CertResponse.certifiedKeyPair.certificate
 *    from the CMMFCertResponse.  The user will get a copy of that certificate
 *    so  the user must call CERT_DestroyCertificate when the return value is 
 *    no longer needed.  The certificate returned will be in the temporary 
 *    certificate database.
 *
 * RETURN:
 *    A pointer to a copy of the certificate contained within the 
 *    CMMFCertResponse.  A return value of NULL indicates an error while trying
 *    to make a copy of the certificate.
 */
extern CERTCertificate*
       CMMF_CertResponseGetCertificate(CMMFCertResponse *inCertResp,
                                       CERTCertDBHandle *inCertdb);

/*
 * FUNCTION: CMMF_KeyRecRepContentGetPKIStatusInfoStatus
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent structure to operate on.
 * NOTES:
 *    This function retrieves the KeyRecRepContent.status.status field of 
 *    the CMMFKeyRecRepContent structure.
 * RETURN:
 *    The CMMFPKIStatus corresponding to the value held in the 
 *    CMMFKeyRecRepContent structure.
 */
extern CMMFPKIStatus 
CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep);

/*
 * FUNCTION: CMMF_KeyRecRepContentGetNewSignCert
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to operate on.
 * NOTES:
 *    This function retrieves the KeyRecRepContent.newSignCert field of the
 *    CMMFKeyRecRepContent structure.  The user must call 
 *    CERT_DestroyCertificate when the return value is no longer needed. The
 *    returned certificate will be in the temporary database.  The user 
 *    must then place the certificate permanently in whatever token the
 *    user determines is the proper destination.  A return value of NULL
 *    indicates the newSigCert field was not present.
 */
extern CERTCertificate*
       CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep);

/*
 * FUNCTION: CMMF_KeyRecRepContentGetCACerts
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to operate on.
 * NOTES:
 *    This function returns a CERTCertList which contains all of the 
 *    certficates that are in the sequence KeyRecRepContent.caCerts
 *    User must call CERT_DestroyCertList when the return value is no longer 
 *    needed.  All of these certificates will be placed in the tempoaray
 *    database.
 *
 * RETURN:
 *    A pointer to the list of caCerts contained in the CMMFKeyRecRepContent
 *    structure.  A return value of NULL indicates the library was not able to 
 *    make a copy of the certifcates.  This may be because there are no caCerts
 *    included in the CMMFKeyRecRepContent strucure or an internal error.  Call
 *    CMMF_KeyRecRepContentHasCACerts to find out if there are any caCerts 
 *    included in 'inKeyRecRep'.
 */
extern CERTCertList*
       CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep);

/*
 * FUNCTION: CMMF_KeyRecRepContentGetNumKeyPairs
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to operate on.
 * RETURN:
 *    This function returns the number of CMMFCertifiedKeyPair structures that
 *    that are stored in the KeyRecRepContent structure.
 */
extern int 
       CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep);

/*
 * FUNCTION: CMMF_KeyRecRepContentGetCertKeyAtIndex
 * INPUTS:
 *    inKeyRecRepContent
 *        The CMMFKeyRecRepContent to operate on.
 *    inIndex
 *        The index of the desired CMMFCertifiedKeyPair
 * NOTES:
 *    This function retrieves the CMMFCertifiedKeyPair structure at the index
 *    'inIndex'.  Valid indexes are 0...(numKeyPairs-1)  The user must call 
 *    CMMF_DestroyCertifiedKeyPair when the return value is no longer needed.
 *
 * RETURN:
 *    A pointer to the Certified Key Pair at the desired index.  A return value
 *    of NULL indicates an error in extracting the Certified Key Pair at the 
 *    desired index.
 */
extern CMMFCertifiedKeyPair*
      CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
					     int                   inIndex);

/*
 * FUNCTION: CMMF_CertifiedKeyPairGetCertificate
 * INPUTS:
 *    inCertKeyPair
 *        The CMMFCertifiedKeyPair to operate on.
 *    inCertdb
 *        The database handle for the database you want this certificate
 *        to wind up in.
 * NOTES:
 *    This function retrieves the certificate at 
 *    CertifiedKeyPair.certOrEncCert.certificate
 *    The user must call CERT_DestroyCertificate when the return value is no
 *    longer needed.  The user must import this certificate as a token object
 *    onto PKCS#11 slot in order to make it a permanent object.  The returned
 *    certificate will be in the temporary database.
 * 
 * RETURN:
 *    A pointer to the certificate contained within the certified key pair.
 *    A return value of NULL indicates an error in creating the copy of the 
 *    certificate.
 */
extern CERTCertificate*
      CMMF_CertifiedKeyPairGetCertificate(CMMFCertifiedKeyPair *inCertKeyPair,
					  CERTCertDBHandle     *inCertdb);

/*
 * FUNCTION: CMMF_POPODecKeyChallContentGetNumChallenges
 * INPUTS:
 *    inKeyChallCont
 *        The CMMFPOPODecKeyChallContent to operate on.
 * RETURN:
 *    This function returns the number of CMMFChallenges are contained in 
 *    the CMMFPOPODecKeyChallContent structure.
 */
extern int CMMF_POPODecKeyChallContentGetNumChallenges
                                  (CMMFPOPODecKeyChallContent *inKeyChallCont);

/*
 * FUNCTION: CMMF_POPODecKeyChallContentGetPublicValue
 * ---------------------------------------------------
 * INPUTS:
 *    inKeyChallCont
 *        The CMMFPOPODecKeyChallContent to operate on.
 *    inIndex
 *        The index of the Challenge within inKeyChallCont to operate on.
 *        Indexes start from 0, ie the Nth Challenge corresponds to index
 *        N-1.
 * NOTES:
 * This function retrieves the public value stored away in the Challenge at
 * index inIndex of inKeyChallCont.
 * RETURN:
 * A pointer to a SECItem containing the public value.  User must call 
 * SECITEM_FreeItem on the return value when the value is no longer necessary.
 * A return value of NULL indicates an error while retrieving the public value.
 */
extern SECItem* CMMF_POPODecKeyChallContentGetPublicValue
                                   (CMMFPOPODecKeyChallContent *inKeyChallCont,
				    int                         inIndex);


/*
 * FUNCTION: CMMF_POPODecKeyChallContentGetRandomNumber
 * INPUTS:
 *    inChallContent
 *        The CMMFPOPODecKeyChallContent to operate on.
 *    inIndex
 *        The index of the challenge to look at.  Valid indexes are 0 through
 *        (CMMF_POPODecKeyChallContentGetNumChallenges(inChallContent) - 1).
 *    inDest
 *        A pointer to a user supplied buffer where the library
 *        can place a copy of the random integer contatained in the
 *        challenge.
 * NOTES:
 *    This function returns the value held in the decrypted Rand structure
 *    corresponding to the random integer.  The user must call 
 *    CMMF_POPODecKeyChallContentDecryptChallenge before calling this function.  Call 
 *    CMMF_ChallengeIsDecrypted to find out if the challenge has been 
 *    decrypted.
 *
 * RETURN:
 *    SECSuccess indicates the witness field has been previously decrypted
 *    and the value for the random integer was successfully placed at *inDest.
 *    Any other return value indicates an error and that the value at *inDest
 *    is not a valid value.
 */
extern SECStatus CMMF_POPODecKeyChallContentGetRandomNumber
                                      (CMMFPOPODecKeyChallContent *inKeyChallCont,
				       int                          inIndex,
				       long                        *inDest);

/*
 * FUNCTION: CMMF_POPODecKeyRespContentGetNumResponses
 * INPUTS:
 *    inRespCont
 *        The POPODecKeyRespContent to operate on.
 * RETURN:
 * This function returns the number of responses contained in inRespContent.
 */
extern int 
 CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont);

/*
 * FUNCTION: CMMF_POPODecKeyRespContentGetResponse
 * INPUTS:
 *    inRespCont
 *        The POPODecKeyRespContent to operate on.
 *    inIndex
 *        The index of the response to retrieve.
 *        The Nth response is at index N-1, ie the 1st response is at index 0,
 *        the 2nd response is at index 1, and so on.
 *    inDest
 *        A pointer to a pre-allocated buffer where the library can put the 
 *        value of the response located at inIndex.
 * NOTES:
 * The function returns the response contained at index inIndex.  
 * CMMFPOPODecKeyRespContent is a structure that the server will generally 
 * get in response to a CMMFPOPODecKeyChallContent.  The server will expect
 * to see the responses in the same order as it constructed them in 
 * the CMMFPOPODecKeyChallContent structure.
 * RETURN:
 * SECSuccess if getting the response at the desired index was successful.  Any
 * other return value indicates an errror.
 */
extern SECStatus
     CMMF_POPODecKeyRespContentGetResponse (CMMFPOPODecKeyRespContent *inRespCont,
					    int                        inIndex,
					    long                      *inDest);

/************************* Destructor Functions ******************************/

/*
 * FUNCTION: CMMF_DestroyCertResponse
 * INPUTS:
 *    inCertResp
 *        The CMMFCertResponse to destroy.
 * NOTES:
 *    This function frees all the memory associated with the CMMFCertResponse
 *    passed in.
 * RETURN:
 *    SECSuccess if freeing the memory was successful.  Any other return value
 *    indicates an error while freeing the memory.
 */
extern SECStatus CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp);

/*
 * FUNCTION: CMMF_DestroyCertRepContent
 * INPUTS:
 *    inCertRepContent
 *        The CMMFCertRepContent to destroy
 * NOTES:
 *    This function frees the memory associated with the CMMFCertRepContent
 *    passed in.
 * RETURN:
 *    SECSuccess if freeing all the memory associated with the 
 *    CMMFCertRepContent passed in is successful.  Any other return value 
 *    indicates an error while freeing the memory.
 */
extern SECStatus 
       CMMF_DestroyCertRepContent (CMMFCertRepContent *inCertRepContent);

/*
 * FUNCTION: CMMF_DestroyKeyRecRepContent
 * INPUTS:
 *    inKeyRecRep
 *        The CMMFKeyRecRepContent to destroy.
 * NOTES:
 *    This function destroys all the memory associated with the 
 *    CMMFKeyRecRepContent passed in.
 *
 * RETURN:
 *    SECSuccess if freeing all the memory is successful.  Any other return 
 *    value indicates an error in freeing the memory.
 */
extern SECStatus 
       CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep);

/*
 * FUNCTION: CMMF_DestroyCertifiedKeyPair
 * INPUTS:
 *    inCertKeyPair
 *        The CMMFCertifiedKeyPair to operate on.
 * NOTES: 
 *    This function frees up all the memory associated with 'inCertKeyPair'
 *
 * RETURN:
 *    SECSuccess if freeing all the memory associated with 'inCertKeyPair'
 *    is successful.  Any other return value indicates an error while trying
 *    to free the memory.
 */
extern SECStatus 
       CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair);

/*
 * FUNCTION: CMMF_DestroyPOPODecKeyRespContent
 * INPUTS:
 *    inDecKeyResp
 *        The CMMFPOPODecKeyRespContent structure to free.
 * NOTES:
 *    This function frees up all the memory associate with the 
 *    CMMFPOPODecKeyRespContent.
 *
 * RETURN:
 *    SECSuccess if freeing up all the memory associated with the
 *    CMMFPOPODecKeyRespContent structure is successful.  Any other
 *    return value indicates an error while freeing the memory.
 */
extern SECStatus
       CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp);


/************************** Miscellaneous Functions *************************/
 
/*
 * FUNCTION: CMMF_CertifiedKeyPairUnwrapPrivKey
 * INPUTS:
 *    inCertKeyPair
 *        The CMMFCertifiedKeyPair to operate on.
 *    inPrivKey
 *        The private key to use to un-wrap the private key
 *    inNickName
 *        This is the nickname that will be associated with the private key
 *        to be unwrapped.
 *    inSlot
 *        The PKCS11 slot where the unwrapped private key should end up.
 *    inCertdb
 *        The Certificate database with which the new key will be associated.
 *    destPrivKey
 *        A pointer to memory where the library can place a pointer to the
 *        private key after importing the key onto the specified slot.
 *    wincx
 *        An opaque pointer that the library will use in a callback function
 *        to get the password if necessary.
 *    
 * NOTES:
 *    This function uses the private key passed in to unwrap the private key
 *    contained within the CMMFCertifiedKeyPair structure. After this 
 *    function successfully returns, the private key has been unwrapped and
 *    placed in the specified slot. 
 *
 * RETURN:
 *    SECSuccess if unwrapping the private key was successful.  Any other 
 *    return value indicates an error while trying to un-wrap the private key.
 */
extern SECStatus 
       CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
					  SECKEYPrivateKey     *inPrivKey,
					  SECItem              *inNickName,
					  PK11SlotInfo         *inSlot,
                                          CERTCertDBHandle     *inCertdb,
					  SECKEYPrivateKey    **destPrivKey,
					  void                 *wincx);

/*
 * FUNCTION: CMMF_KeyRecRepContentHasCACerts
 * INPUTS:
 *    inKeyRecRecp
 *        The CMMFKeyRecRepContent to operate on.
 * RETURN:
 *    This function returns PR_TRUE if there are one or more certificates in 
 *    the sequence KeyRecRepContent.caCerts within the CMMFKeyRecRepContent
 *    structure.  The function will return PR_FALSE if there are 0 certificate
 *    in the above mentioned sequence.
 */
extern PRBool 
       CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep);

/*
 * FUNCTION: CMMF_POPODecKeyChallContDecryptChallenge
 * INPUTS:
 *    inChalCont
 *        The CMMFPOPODecKeyChallContent to operate on.
 *    inIndex
 *        The index of the Challenge to operate on.  The 1st Challenge is
 *        at index 0, the second at index 1 and so forth.
 *    inPrivKey
 *        The private key to use to decrypt the witness field.
 * NOTES:
 *    This function uses the private key to decrypt the challenge field
 *    contained in the appropriate challenge.  Make sure the private key matches 
 *    the public key that was used to encrypt the witness.  Use 
 *    CMMF_POPODecKeyChallContentGetPublicValue to get the public value of
 *    the key used to encrypt the witness and then use that to determine the
 *    appropriate private key.  This can be done by calling PK11_MakeIDFromPubKey
 *    and then passing that return value to PK11_FindKeyByKeyID.  The creator of 
 *    the challenge will most likely be an RA that has the public key
 *    from a Cert request.  So the private key should be the private key
 *    associated with public key in that request.  This function will also
 *    verify the witness field of the challenge.  This function also verifies
 *    that the sender and witness hashes match within the challenge.
 *
 * RETURN:
 *    SECSuccess if decrypting the witness field was successful.  This does
 *    not indicate that the decrypted data is valid, since the private key 
 *    passed in may not be the actual key needed to properly decrypt the 
 *    witness field.  Meaning that there is a decrypted structure now, but
 *    may be garbage because the private key was incorrect.
 *    Any other return value indicates the function could not complete the
 *    decryption process.
 */
extern SECStatus 
  CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
					   int                         inIndex,
					   SECKEYPrivateKey           *inPrivKey);

/*
 * FUNCTION: CMMF_DestroyPOPODecKeyChallContent
 * INPUTS:
 *    inDecKeyCont
 *        The CMMFPOPODecKeyChallContent to free
 * NOTES:
 *    This function frees up all the memory associated with the 
 *    CMMFPOPODecKeyChallContent 
 * RETURN:
 *    SECSuccess if freeing up all the memory associatd with the 
 *    CMMFPOPODecKeyChallContent is successful.  Any other return value
 *    indicates an error while freeing the memory.
 *
 */
extern SECStatus 
 CMMF_DestroyPOPODecKeyChallContent (CMMFPOPODecKeyChallContent *inDecKeyCont);

SEC_END_PROTOS
#endif /* _CMMF_H_ */
