/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef _SECOID_H_
#define _SECOID_H_

#include "utilrename.h"

/*
 * secoid.h - public data structures and prototypes for ASN.1 OID functions
 */

#include "plarena.h"

#include "seccomon.h"
#include "secoidt.h"
#include "secasn1t.h"

SEC_BEGIN_PROTOS

extern const SEC_ASN1Template SECOID_AlgorithmIDTemplate[];

/* This functions simply returns the address of the above-declared template. */
SEC_ASN1_CHOOSER_DECLARE(SECOID_AlgorithmIDTemplate)

/*
 * OID handling routines
 */
extern SECOidData *SECOID_FindOID( const SECItem *oid);
extern SECOidTag SECOID_FindOIDTag(const SECItem *oid);
extern SECOidData *SECOID_FindOIDByTag(SECOidTag tagnum);
extern SECOidData *SECOID_FindOIDByMechanism(unsigned long mechanism);

/****************************************/
/*
** Algorithm id handling operations
*/

/*
** Fill in an algorithm-ID object given a tag and some parameters.
** 	"aid" where the DER encoded algorithm info is stored (memory
**	   is allocated)
**	"tag" the tag number defining the algorithm 
**	"params" if not NULL, the parameters to go with the algorithm
*/
extern SECStatus SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *aid,
				   SECOidTag tag, SECItem *params);

/*
** Copy the "src" object to "dest". Memory is allocated in "dest" for
** each of the appropriate sub-objects. Memory in "dest" is not freed
** before memory is allocated (use SECOID_DestroyAlgorithmID(dest, PR_FALSE)
** to do that).
*/
extern SECStatus SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *dest,
				        const SECAlgorithmID *src);

/*
** Get the tag number for the given algorithm-id object.
*/
extern SECOidTag SECOID_GetAlgorithmTag(const SECAlgorithmID *aid);

/*
** Destroy an algorithm-id object.
**	"aid" the certificate-request to destroy
**	"freeit" if PR_TRUE then free the object as well as its sub-objects
*/
extern void SECOID_DestroyAlgorithmID(SECAlgorithmID *aid, PRBool freeit);

/*
** Compare two algorithm-id objects, returning the difference between
** them.
*/
extern SECComparison SECOID_CompareAlgorithmID(SECAlgorithmID *a,
					   SECAlgorithmID *b);

extern PRBool SECOID_KnownCertExtenOID (SECItem *extenOid);

/* Given a tag number, return a string describing it.
 */
extern const char *SECOID_FindOIDTagDescription(SECOidTag tagnum);

/* Add a dynamic SECOidData to the dynamic OID table.
** Routine copies the src entry, and returns the new SECOidTag.
** Returns SEC_OID_INVALID if failed to add for some reason.
*/
extern SECOidTag SECOID_AddEntry(const SECOidData * src);

/*
 * initialize the oid data structures.
 */
extern SECStatus SECOID_Init(void);

/*
 * free up the oid data structures.
 */
extern SECStatus SECOID_Shutdown(void);

/* if to->data is not NULL, and to->len is large enough to hold the result,
 * then the resultant OID will be copyed into to->data, and to->len will be
 * changed to show the actual OID length.
 * Otherwise, memory for the OID will be allocated (from the caller's 
 * PLArenaPool, if pool is non-NULL) and to->data will receive the address
 * of the allocated data, and to->len will receive the OID length.
 * The original value of to->data is not freed when a new buffer is allocated.
 * 
 * The input string may begin with "OID." and this still be ignored.
 * The length of the input string is given in len.  If len == 0, then 
 * len will be computed as strlen(from), meaning it must be NUL terminated.
 * It is an error if from == NULL, or if *from == '\0'.
 */
extern SECStatus SEC_StringToOID(PLArenaPool *pool, SECItem *to, 
                                 const char *from, PRUint32 len);

extern void UTIL_SetForkState(PRBool forked);

/*
 * Accessor functions for new opaque extended SECOID table.
 * Any of these functions may return SECSuccess or SECFailure with the error 
 * code set to SEC_ERROR_UNKNOWN_OBJECT_TYPE if the SECOidTag is out of range.
 */

/* The Get function outputs the 32-bit value associated with the SECOidTag.
 * Flags bits are the NSS_USE_ALG_ #defines in "secoidt.h".
 * Default value for any algorithm is 0xffffffff (enabled for all purposes).
 * No value is output if function returns SECFailure.
 */
extern SECStatus NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue);

/* The Set function modifies the stored value according to the following
 * algorithm:
 *   policy[tag] = (policy[tag] & ~clearBits) | setBits;
 */
extern SECStatus
NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits);


SEC_END_PROTOS

#endif /* _SECOID_H_ */
