/* ***************************************************************** *
 * Copyright 1998 International Business Machines Corporation. All   *
 * Rights Reserved.                                                  *
 *                                                                   *
 * Please read this carefully.  Your use of this reference           *
 * implementation of certain of the IETF public-key infrastructure   *
 * specifications ("Software") indicates your acceptance of the      *
 * following.  If you do not agree to the following, do not install  *
 * or use any of the Software.                                       *
 *                                                                   *
 * Permission to use, reproduce, distribute and create derivative    *
 * works from the Software ("Software Derivative Works"), and to     *
 * distribute such Software Derivative Works is hereby granted to    *
 * you by International Business Machines Corporation ("IBM").  This *
 * permission includes a license under the patents of IBM that are   *
 * necessarily infringed by your use of the Software as provided by  *
 * IBM.                                                              *
 *                                                                   *
 * IBM licenses the Software to you on an "AS IS" basis, without     *
 * warranty of any kind.  IBM HEREBY EXPRESSLY DISCLAIMS ALL         *
 * WARRANTIES OR CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF       *
 * MERCHANTABILITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR    *
 * PURPOSE.  You are solely responsible for determining the          *
 * appropriateness of using this Software and assume all risks       *
 * associated with the use of this Software, including but not       *
 * limited to the risks of program errors, damage to or loss of      *
 * data, programs or equipment, and unavailability or interruption   *
 * of operations.                                                    *
 *                                                                   *
 * IBM WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, *
 * INCIDENTAL, OR  INDIRECT DAMAGES OR FOR ANY ECONOMIC              *
 * CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN   *
 * IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  IBM  *
 * will not be liable for the loss of, or damage to, your records or *
 * data, or any damages claimed by you based on a third party claim. *
 *                                                                   *
 * IBM wishes to obtain your feedback to assist in improving the     *
 * Software.  You grant IBM a world-wide, royalty-free right to use, *
 * copy, distribute, sublicense and prepare derivative works based   *
 * upon any feedback, including materials, error corrections,        *
 * Software Derivatives, enhancements, suggestions and the like that *
 * you provide to IBM relating to the Software (this does not        *
 * include products for which you charge a royalty and distribute to *
 * IBM under other terms and conditions).                            *
 *                                                                   *
 * You agree to distribute the Software and any Software Derivatives *
 * under a license agreement that: 1) is sufficient to notify all    *
 * licensees of the Software and Software Derivatives that IBM       *
 * assumes no liability for any claim that may arise regarding the   *
 * Software or Software Derivatives, and 2) that disclaims all       *
 * warranties, both express and implied, from IBM regarding the      *
 * Software and Software Derivatives.  (If you include this          *
 * Agreement with any distribution of the Software or Software       *
 * Derivatives you will have met this requirement.)  You agree that  *
 * you will not delete any copyright notices in the Software.        *
 *                                                                   *
 * This Agreement is the exclusive statement of your rights in the   *
 * Software as provided by IBM.   Except for the rights granted to   *
 * you in the second paragraph above, You are not granted any other  *
 * patent rights, including but not limited to the right to make     *
 * combinations of the Software with products that infringe IBM      *
 * patents. You agree to comply with all applicable laws and         *
 * regulations, including all export and import laws and regulation. *
 * This Agreement is governed by the laws of the State of New York.  *
 * This Agreement supersedes all other communications,               *
 * understandings or agreements we may have had prior to this        *
 * Agreement.                                                        *
 * ***************************************************************** */


#ifndef JKL_H_
#define JKL_H_


//------------------------------------------------------------
// includes
//------------------------------------------------------------

#include "cssm.h"
#include "x509.h"
#include "pkcs.h"
#include "rsa.h"
#include "dsa.h"


//*****************************************************************************
//
// High-Level Cryptographic APIs
//
// NOTE: These APIs automatically select a suitable CSP module from those 
// currently installed on your machine.  The default behavior is to use Cylink 
// CSP whenever possible; BSAFE CSP is used in cases where Cylink does not 
// provide support for a specific algorithm.  Failure to find a suitable CSP is
// indicated by CSSM_CSP_OPERATION_UNSUPPORTED error code.
//
// Supported key-pair algorithms:
//
//    CSSM_ALGID_DSA
//    CSSM_ALGID_RSA
//
// Supported signature algorithms:
//
//    CSSM_ALGID_SHA1WithDSA
//    CSSM_ALGID_MD5WithRSA
//    CSSM_ALGID_MD2WithRSA
//    CSSM_ALGID_SHA1WithRSA
//
// Supported digest algorithms:
//
//    CSSM_ALGID_MD2
//    CSSM_ALGID_MD4
//    CSSM_ALGID_MD5
//    CSSM_ALGID_SHA1
//
// DES Note: Triple DES routines all accept numOfKeys parameter with value 
// 1, 2, or 3.  BSAFE supports 3 keys only; Cylink supports 1,2,3 keys
//
//*****************************************************************************


// NOTE: This API must be called before any other to initialize crypto library

EXPORTFN(uint32,
         JKL_Initialize,
         (CSSM_MEMORY_FUNCS& memoryFuncs));

EXPORTFN(uint32,
         JKL_DigestData,
         (CSSM_ALGORITHMS cssmDigestAlgorithm,
          const CSSM_DATA& cssmDataToDigest,
          asn_octetstring& digest));

EXPORTFN(uint32,
         JKL_GenerateRandomData,
         (uint32 randomDataSize,
          asn_octetstring& randomData));

EXPORTFN(uint32, 
         JKL_GenerateKeyPair,
         (CSSM_ALGORITHMS cssmKeyPairType,
          uint32 keySizeInBits,
          SubjectPublicKeyInfo& subjectPublicKeyInfo,
          PrivateKeyInfo& privateKeyInfo));

EXPORTFN(uint32, 
         JKL_VerifyData,
         (const AlgorithmIdentifier& algorithmIdentifier,
          const SubjectPublicKeyInfo& signerPublicKeyInfo,
          const asn_bitstring& signature,
          const asn_object& dataToVerify,
          bool& isVerified));

EXPORTFN(uint32, 
         JKL_VerifyData,
         (const AlgorithmIdentifier& algorithmIdentifier,
          const SubjectPublicKeyInfo& signerPublicKeyInfo,
          const asn_bitstring& signature,
          const buffer_t& dataToVerify,
          bool& isVerified));

EXPORTFN(uint32, 
         JKL_ValidateCertificateSignature,
         (const x509_certificate& subject, 
          const x509_certificate& issuer,
          bool& isVerified));

EXPORTFN(uint32, 
         JKL_ValidateCRLSignature,
         (const CertificateList& crl, 
          const x509_certificate& issuer,
          bool& isVerified));

EXPORTFN(uint32, 
         JKL_SignData,
         (const PrivateKeyInfo& privateKeyInfo,
          const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          CSSM_ALGORITHMS cssmSignatureAlgorithmID,
          const buffer_t& dataToSign,
          asn_bitstring& signature));
          
EXPORTFN(uint32, 
         JKL_SignData,
         (const PrivateKeyInfo& privateKeyInfo,
          const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          CSSM_ALGORITHMS cssmSignatureAlgorithmID,
          const asn_object& dataToSign,
          asn_bitstring& signature));

EXPORTFN(uint32, 
         JKL_SignCertificate,
         (const PrivateKeyInfo& privateKeyInfo,
          const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          CSSM_ALGORITHMS cssmSignatureAlgorithmID,
          x509_certificate& certToBeSigned));

EXPORTFN(uint32, 
         JKL_SignCRL,
         (const PrivateKeyInfo& privateKeyInfo,
          const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          CSSM_ALGORITHMS cssmSignatureAlgorithmID,
          const CertificateList& crlToBeSigned));

EXPORTFN(uint32,
         JKL_3DES_GenerateKey,
         (asn_octetstring& desKey,
          asn_octetstring& IV,
          int numOfKeys));

EXPORTFN(uint32,
         JKL_3DES_EncryptData,
         (const asn_octetstring& desKey,
          const asn_octetstring& IV,
          int numOfKeys,
          const asn_octetstring& dataToEncrypt,
          asn_octetstring& encryptedData));

EXPORTFN(uint32,
         JKL_3DES_DecryptData,
         (const asn_octetstring& desKey,
          const asn_octetstring& IV,
          int numOfKeys,
          const asn_octetstring& dataToDecrypt,
          asn_octetstring& decryptedData));

EXPORTFN(uint32,
         JKL_ExtractRSAPublicKey,
         (const SubjectPublicKeyInfo& subjectPublicKeyInfo, 
          RSAPublicKey& rsaPublicKey));

EXPORTFN(uint32,
         JKL_ExtractDSAPublicKey,
         (const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          DssParms& dssParms,
          asn_integer& dsaPublicKey));

EXPORTFN(uint32,
         JKL_ExtractRSAPrivateKey,
         (const PrivateKeyInfo& privateKeyInfo,
          RSAPrivateKey& rsaPrivateKey));

EXPORTFN(uint32,
         JKL_ExtractDSAPrivateKey,
         (const PrivateKeyInfo& privateKeyInfo,
          DssPrivateParms& dssPrivateParms,
          DssPrivateKey& privatekey));

EXPORTFN(uint32,
         JKL_ComputeKeySizeInBits,
         (const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          long& keySizeInBits));

EXPORTFN(uint32,
         JKL_ComputeKeySizeInBits,
         (const PrivateKeyInfo& privateKeyInfo,
          long& keySizeInBits));

EXPORTFN(uint32,
         JKL_ComputeKeySizeInBits,
         (const asn_integer& modulus,
          long& keySizeInBits));

EXPORTFN(uint32,
         JKL_SetPreferredCSP,
         (const CSSM_GUID& cssmGUID));

EXPORTFN(bool,
         JKL_AlgorithmIsSupported,
         (const CSSM_GUID& cssmGUID, 
          uint32 algorithmID));

EXPORTFN(uint32,
         JKL_SetPreferredCSP,
         (const CSSM_GUID& cssmGUID, 
          uint32 algorithmID));

EXPORTFN(uint32,
         JKL_GetPreferredCSP,
         (CSSM_GUID& cssmGUID, 
          uint32 algorithmID));


//*****************************************************************************
//
// Low-Level Cryptographic APIs
//
// NOTE: You should never need to use these low-levels APIs unless you really
// need to access CDSA directly.  The APIs are similar to their high-level 
// counterparts, but use CSSM instead of ASN data structures.  You must deallocate 
// any CSSM data structures allocated on your behalf.  Specifically, these are 
// any non-const CSSM structures (CSSM_DATA, CSSM_KEY) that appear on the APIs 
// in this module.  All CSSM memory is allocated with the MemoryFuncs you supplied 
// on the JKL_InitializeCSSM API.  Utility APIs called JKL_FreeData are provided 
// for this purpose.
//
//*****************************************************************************


EXPORTFN(uint32,
         JKL_DigestData,
         (CSSM_CSP_HANDLE cspHandle,
          CSSM_ALGORITHMS cssmDigestAlgorithm,
          const CSSM_DATA& cssmDataToDigest,
          asn_octetstring& digest));

EXPORTFN(uint32,
         JKL_GenerateRandomData,
         (CSSM_CSP_HANDLE cspHandle,
          uint32 randomDataSize,
          CSSM_ALGORITHMS cssmDigestAlgorithm,
          CSSM_DATA& cssmRandomData));      // caller must free

EXPORTFN(uint32, 
         JKL_GenerateKeyPair,
         (CSSM_CSP_HANDLE cspHandle,
          CSSM_ALGORITHMS cssmKeyPairType,
          uint32 modulusBits,               // e.g., 512 or 1024
          CSSM_KEY& cssmPublicKey,          // caller must free
          CSSM_KEY& cssmPrivateKey));       // caller must free

EXPORTFN(uint32, 
         JKL_VerifyData,
         (CSSM_CSP_HANDLE cspHandle,
          CSSM_ALGORITHMS cssmSignatureAlgorithm,
          CSSM_KEY& cssmPublicKey,
          const CSSM_DATA& cssmSignature,
          const CSSM_DATA& cssmDataToVerify,
          CSSM_BOOL& cssmIsVerified));

EXPORTFN(uint32, 
         JKL_VerifyData,
         (CSSM_CSP_HANDLE cspHandle,
          const AlgorithmIdentifier& algorithmIdentifier,
          const SubjectPublicKeyInfo& signerPublicKeyInfo,
          const asn_bitstring& signature,
          const buffer_t& dataToVerify,
          bool& isVerified));

EXPORTFN(uint32, 
         JKL_ValidateCertificateSignature,
         (const x509_certificate& subject, 
          const x509_certificate& issuer,
          CSSM_CSP_HANDLE cspHandle,
          bool& isVerified));

EXPORTFN(uint32, 
         JKL_ValidateCRLSignature,
         (const CertificateList& crl, 
          const x509_certificate& issuer,
          CSSM_CSP_HANDLE cspHandle,
          bool& isVerified));

EXPORTFN(uint32, 
         JKL_SignData,
         (CSSM_CSP_HANDLE cspHandle,
          CSSM_ALGORITHMS cssmAlgorithmID,
          const CSSM_KEY& cssmPrivateKey,
          const CSSM_DATA& cssmDataToSign,
          CSSM_DATA& cssmSignature));       // caller must free

EXPORTFN(uint32, 
         JKL_SignCertificate,
         (x509_certificate& certToBeSigned, 
          CSSM_CSP_HANDLE cspHandle, 
          CSSM_ALGORITHMS cssmSignatureAlgorithmID,
          const CSSM_KEY& cssmSignerPrivateKey));

EXPORTFN(uint32, 
         JKL_SignCRL,
         (CertificateList& crlToBeSigned, 
          CSSM_CSP_HANDLE cspHandle, 
          CSSM_ALGORITHMS cssmSignatureAlgorithmID,
          const CSSM_KEY& cssmSignerPrivateKey));

EXPORTFN(uint32,
         JKL_3DES_GenerateKey,
         (CSSM_CSP_HANDLE cspHandle,
          CSSM_KEY& cssmSecretKey,          // caller must free
          int numOfKeys));

EXPORTFN(uint32,
         JKL_DES_GenerateIV,
         (CSSM_CSP_HANDLE cspHandle,
          CSSM_DATA& cssmIV));              // caller must free

EXPORTFN(uint32,
         JKL_3DES_EncryptData,
         (CSSM_CSP_HANDLE cspHandle,
          int numOfKeys,
          const CSSM_DATA& cssmIV,
          const CSSM_KEY& cssmSecretKey,
          const CSSM_DATA& cssmDataToEncrypt,
          CSSM_DATA& cssmEncryptedData));   // caller must free

EXPORTFN(uint32,
         JKL_3DES_DecryptData,
         (CSSM_CSP_HANDLE cspHandle,
          int numOfKeys,
          const CSSM_DATA& cssmIV,
          const CSSM_KEY& cssmSecretKey,
          const CSSM_DATA& cssmDataToDecrypt,
          CSSM_DATA& cssmDecryptedData));   // caller must free


//*****************************************************************************
//
// Utility Conversion Routines from CSSM to ASN
//
// NOTE: Should only be used in conjunction with Low-Level Cryptographic APIs.
// Each CDSA CSP module has it own data format for keys, signatures, and digest.  
// These APIs convert from a CSP-specific format to DER representation.
//
//*****************************************************************************


EXPORTFN(uint32, 
         JKL_cssm_to_asn, 
         (const CSSM_KEY& cssmPublicKey,
          SubjectPublicKeyInfo& subjectPublicKeyInfo));

EXPORTFN(uint32, 
         JKL_cssm_to_asn, 
         (const CSSM_KEY& cssmPrivateKey,
          PrivateKeyInfo& privateKeyInfo));

EXPORTFN(uint32, 
         JKL_cssm_to_asn, 
         (CSSM_ALGORITHMS cssmSignatureAlgorithmID,
          AlgorithmIdentifier& algorithmIdentifier));

EXPORTFN(uint32, 
         JKL_cssm_to_asn, 
         (const CSSM_DATA& cssmSignature,
          asn_bitstring& signature,
          const CSSM_GUID& cssmCspGUID));

EXPORTFN(uint32, 
         JKL_cssm_to_asn, 
         (const CSSM_DATA& cssmDigest,
          asn_octetstring& digest,
          const CSSM_GUID& cssmCspGUID));


//*****************************************************************************
//
// Utility Conversion Routines from ASN to CSSM
//
// NOTE: Should only be used in conjunction with Low-Level Cryptographic APIs.
// Each CDSA CSP module has it own data format for keys, signatures, and digest.  
// These APIs convert from DER representation to CSP-specific formats.
//
//*****************************************************************************


EXPORTFN(uint32, 
         JKL_asn_to_cssm,
         (const asn_octetstring& desKey,
          int numOfKeys,
          CSSM_KEY& cssmSecretKey,     // caller must free
          const CSSM_GUID& cssmCspGUID));

EXPORTFN(uint32, 
         JKL_asn_to_cssm,
         (const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          CSSM_KEY& cssmPublicKey,     // caller must free
          const CSSM_GUID& cssmCspGUID));

EXPORTFN(uint32, 
         JKL_asn_to_cssm,
         (const PrivateKeyInfo& privateKeyInfo,
          const SubjectPublicKeyInfo& subjectPublicKeyInfo,
          CSSM_KEY& cssmPrivateKey,    // caller must free
          const CSSM_GUID& cssmCspGUID));

EXPORTFN(uint32, 
         JKL_asn_to_cssm,
         (const AlgorithmIdentifier& algorithmIdentifier,
          CSSM_ALGORITHMS& cssmSignatureAlgorithmID)); 

EXPORTFN(uint32, 
         JKL_asn_to_cssm,
         (const asn_bitstring& signature,
          CSSM_DATA& cssmSignature,    // caller must free
          const CSSM_GUID& cssmCspGUID));


//*****************************************************************************
//
// Misc. CSSM Utility Routines
//
// NOTE: Should only be used in conjunction with Low-Level Cryptographic APIs.
//
//*****************************************************************************


EXPORTFN(void,
         JKL_FreeData,
         (CSSM_DATA& cssmDataToFree));

EXPORTFN(void,
         JKL_FreeData,
         (CSSM_DATA_PTR& cssmDataToFreePtr,
          uint32 numOfElementsToFree));

EXPORTFN(void,
         JKL_FreeData,
         (CSSM_KEY& cssmKeyDataToFree));

EXPORTFN(bool,
         JKL_CompareData,
         (const CSSM_DATA& cssmData1, 
          const CSSM_DATA& cssmData2));


//*****************************************************************************
//
// Deprecated Methods
//
//*****************************************************************************


// *** Reason: byte-order of cssmDataToDisgest is CSP-specific

EXPORTFN(uint32,
         JKL_DigestData,
         (CSSM_CSP_HANDLE cspHandle,
          CSSM_ALGORITHMS cssmDigestAlgorithm,
          const CSSM_DATA& cssmDataToDigest,
          CSSM_DATA& cssmDigest));          // caller must free

// *** Reason: caller now provides digest algorithm to use as parameter

EXPORTFN(uint32,
         JKL_GenerateRandomData,
         (CSSM_CSP_HANDLE cspHandle,
          uint32 randomDataSize,
          CSSM_DATA& cssmRandomData));      // caller must free

// *** Reason: this code is only for CSP, not TPs

EXPORTFN(uint32, 
         JKL_AttachTP,
         (const CSSM_GUID& cssmSelectedGUID, 
          CSSM_TP_HANDLE& tpHandle));


//------------------------------------------------------------
// GUID Utility Methods
//------------------------------------------------------------

EXPORTFN(const CSSM_GUID_PTR,
         JKL_Get_SwCsp_GUID,
         ());

EXPORTFN(const CSSM_GUID_PTR,
         JKL_Get_CylinkCsp_GUID,
         ());

EXPORTFN(const CSSM_GUID_PTR,
         JKL_Get_JonahTp_GUID,
         ());

EXPORTFN(uint32, 
         JKL_InitializeCSSM,
         (CSSM_MEMORY_FUNCS& memoryFuncs));

//------------------------------------------------------------
// CDSA Framework initialization and module management
//------------------------------------------------------------

EXPORTFN(uint32, 
         JKL_FindBestCSP,
         (CSSM_CSP_HANDLE& cspHandle, 
          uint32 cssmAlgorithmID));

EXPORTFN(uint32, 
         JKL_AttachCSP,
         (const CSSM_GUID& cssmSelectedGUID, 
          CSSM_CSP_HANDLE& cspHandle));

EXPORTFN(uint32, 
         JKL_ModuleDetach,
         (CSSM_MODULE_HANDLE cssmModuleHandle));


#endif   // JKL_H_
