/* ***************************************************************** *
 * 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.                                                        *
 * ***************************************************************** */

// 
// ASN.1 class definitions for the data structures defined in the RSA
// PKCS series.
//

#ifndef _PKCS_H_
#define _PKCS_H_

#include <asnbase.h>
#include <asnstrng.h>
#include <asnnames.h>
#include <x509.h>

// RSA PKCS OIDs
#define PKCS7_DATA_ID			"1.2.840.113549.1.7.1"
#define PKCS7_ENCRYPTED_DATA_ID		"1.2.840.113549.1.7.6"
#define PKCS9_FRIENDLYNAME		"1.2.840.113549.1.9.20"
#define PKCS9_LOCALKEYID		"1.2.840.113549.1.9.21"
#define PKCS9_CERTTYPE_X509		"1.2.840.113549.1.9.22.1"
#define PKCS9_CERTTYPE_SDSI		"1.2.840.113549.1.9.22.2"
#define PKCS9_CRLTYPE_X509		"1.2.840.113549.1.9.23.1"
#define PKCS12_PBE_SHA1_40BIT_RC2	"1.2.840.113549.1.12.1.6"
#define PKCS12_PBE_SHA1_128BIT_RC2	"1.2.840.113549.1.12.1.5"
#define PKCS12_PBE_SHA1_2KEY_3DES	"1.2.840.113549.1.12.1.4"
#define PKCS12_PBE_SHA1_3KEY_3DES	"1.2.840.113549.1.12.1.3"
#define PKCS12_PBE_SHA1_40BIT_RC4	"1.2.840.113549.1.12.1.2"
#define PKCS12_PBE_SHA1_128BIT_RC4	"1.2.840.113549.1.12.1.1"
#define PKCS12_KEYBAG			"1.2.840.113549.1.12.10.1.1"
#define PKCS12_SHROUDED_KEYBAG		"1.2.840.113549.1.12.10.1.2"
#define PKCS12_CERTBAG			"1.2.840.113549.1.12.10.1.3"
#define PKCS12_CRLBAG			"1.2.840.113549.1.12.10.1.4"
#define PKCS12_SECRETBAG		"1.2.840.113549.1.12.10.1.5"
#define PKCS12_SAFECONTENTSBAG		"1.2.840.113549.1.12.10.1.6"

#define PKCS12_V3		3


// Generic definitions

template class EXPORTCLASS asn_sequenceof<x509_certificate>;
class EXPORTCLASS CertList : public asn_sequenceof<x509_certificate> {
public:
  CertList(security_t s = ASN_PUBLIC) : asn_sequenceof<x509_certificate> (s) {
	};
};


class EXPORTCLASS Attribute	: public asn_sequence {
public:
  asn_oid		attributeType;
  asn_any		attributeValue;
  Attribute(security_t s = ASN_PUBLIC) : asn_sequence(s) {
    register_child(&attributeType);
    register_child(&attributeValue);
  };
};
template class EXPORTCLASS asn_setof<Attribute>;

class EXPORTCLASS Attributes : public asn_setof<Attribute> {
public:
  Attributes(security_t s = ASN_PUBLIC) : asn_setof<Attribute> (s) {
  };
};


// PKCS #7 Version 1.5 definitions

typedef asn_oid		ContentType;
typedef asn_octetstring	Data;
typedef asn_octetstring	Digest;

class EXPORTCLASS EncryptedContentInfo : public asn_sequence {
public:
  ContentType			contentType;
  AlgorithmIdentifier	contentEncryptionAlgorithm;
  asn_implicit<asn_octetstring, CLASS_CONTEXT_SPECIFIC, 0>	encryptedContent;
  EncryptedContentInfo(security_t s = ASN_PUBLIC) : asn_sequence(s) {
    encryptedContent.set_optional();
    register_child(&contentType);
    register_child(&contentEncryptionAlgorithm);
    register_child(&encryptedContent);
  };
};

class EXPORTCLASS EncryptedData : public asn_sequence {
public:
  asn_integer				version;
  EncryptedContentInfo	encryptedContentInfo;
  EncryptedData(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&version);
    register_child(&encryptedContentInfo);
  };
};

class EXPORTCLASS IssuerAndSerialNumber : public asn_sequence {
public:
  asn_x500name	issuer;
  asn_integer	serialNumber;
  IssuerAndSerialNumber(security_t s = ASN_PUBLIC) : asn_sequence(s) {
    register_child(&issuer);
    register_child(&serialNumber);
  };
};
  
class EXPORTCLASS RecipientInfo : public asn_sequence {
public:
  asn_integer		version;
  IssuerAndSerialNumber	issuerAndSerialNumber;
  AlgorithmIdentifier	keyEncryptionAlgorithm;
  asn_octetstring	encryptedKey;
  RecipientInfo(security_t s = ASN_PUBLIC) : asn_sequence(s) {
    register_child(&version);
    register_child(&issuerAndSerialNumber);
    register_child(&keyEncryptionAlgorithm);
    register_child(&encryptedKey);
  };
};

template class EXPORTCLASS asn_sequenceof<RecipientInfo>;
class EXPORTCLASS RecipientInfos : public asn_sequenceof<RecipientInfo> {
public:
  RecipientInfos(security_t s = ASN_PUBLIC) : asn_sequenceof<RecipientInfo> (s) {
  };
};

class EXPORTCLASS EnvelopedData : public asn_sequence {
public:
  asn_integer		version;
  RecipientInfos	recipientInfos;
  EncryptedContentInfo	encryptedContentInfo;
  EnvelopedData(security_t s = ASN_PUBLIC) : asn_sequence(s) {
    register_child(&version);
    register_child(&recipientInfos);
    register_child(&encryptedContentInfo);
  };
};


// This would normally by a asn_any, but Netscape likes to use
// idefinite length encoding, so we make it a choice.
class EXPORTCLASS Content : public asn_choice {
public:
  Data			data;
  EncryptedData	encryptedData;
  Content(security_t s = ASN_PUBLIC) : asn_choice() {
    register_child(&data);
    register_child(&encryptedData);
  };
};

template class EXPORTCLASS asn_explicit<Content, CLASS_CONTEXT_SPECIFIC, 0>;
class EXPORTCLASS ContentInfo : public asn_sequence {
public:
  ContentType						contentType;
  asn_explicit<Content, CLASS_CONTEXT_SPECIFIC, 0>	content;
  ContentInfo(security_t s = ASN_PUBLIC) : asn_sequence() {
    content.set_optional();
    register_child(&contentType);
    register_child(&content);
  };
};

class EXPORTCLASS DigestInfo : public asn_sequence {
public:
  AlgorithmIdentifier	digestAlgorithm;
  Digest		digest;
  DigestInfo(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&digestAlgorithm);
    register_child(&digest);
  };
};

// PKCS #8 V1.2 definitions

template class EXPORTCLASS asn_implicit<Attributes, CLASS_CONTEXT_SPECIFIC, 0>;
class EXPORTCLASS PrivateKeyInfo : public asn_sequence {
public:
  asn_integer		version;
  AlgorithmIdentifier	privateKeyAlgorithm;
  asn_octetstring	privateKey;
  asn_implicit<Attributes, CLASS_CONTEXT_SPECIFIC, 0>	attributes;
  PrivateKeyInfo(security_t s = ASN_PUBLIC) : asn_sequence() {
    attributes.set_optional();
    register_child(&version);
    register_child(&privateKeyAlgorithm);
    register_child(&privateKey);
    register_child(&attributes);
  };
};

template class EXPORTCLASS asn_sequenceof<PrivateKeyInfo>;

class EXPORTCLASS KeyList : public asn_sequenceof<PrivateKeyInfo> {
public:
  KeyList(security_t s = ASN_PUBLIC) : asn_sequenceof<PrivateKeyInfo> (s) {
  };
};

class EXPORTCLASS EncryptedPrivateKeyInfo : public asn_sequence {
public:
  AlgorithmIdentifier	encryptionAlgorithm;
  asn_octetstring	encryptedData;
  EncryptedPrivateKeyInfo(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&encryptionAlgorithm);
    register_child(&encryptedData);
  };
};

// PKCS #12 Draft definitions

typedef asn_octetstring		LocalKeyID;
typedef PrivateKeyInfo		KeyBag;
typedef EncryptedPrivateKeyInfo	PKCS8ShroudedKeyBag;

template class EXPORTCLASS asn_sequenceof<ContentInfo>;
class EXPORTCLASS AuthenticatedSafes : public asn_sequenceof<ContentInfo> {
public:
  AuthenticatedSafes(security_t s = ASN_PUBLIC) : asn_sequenceof<ContentInfo> (s) {
  };
};

class EXPORTCLASS pkcs_12PbeParams : public asn_sequence {
public:
  asn_octetstring	salt;
  asn_integer		iterationCount;
  pkcs_12PbeParams(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&salt);
    register_child(&iterationCount);
  };
};

template class EXPORTCLASS asn_explicit<asn_any, CLASS_CONTEXT_SPECIFIC, 0>;
class EXPORTCLASS SafeBag : public asn_sequence {
public:
  asn_oid						bagType;
  asn_explicit<asn_any, CLASS_CONTEXT_SPECIFIC, 0>	bagContent;
  Attributes						bagAttributes;
  SafeBag(security_t s = ASN_PUBLIC) : asn_sequence() {
    bagAttributes.set_optional();
    register_child(&bagType);
    register_child(&bagContent);
    register_child(&bagAttributes);
  };
};

template class EXPORTCLASS asn_sequenceof<SafeBag>;
class EXPORTCLASS SafeContents : public asn_sequenceof<SafeBag> {
public:
  SafeContents(security_t s = ASN_PUBLIC) : asn_sequenceof<SafeBag> (s) {
  };
};
typedef SafeContents	SafeContentsBag;

class EXPORTCLASS CertBag : public asn_sequence {
public:
  asn_oid						certType;
  asn_explicit<asn_any, CLASS_CONTEXT_SPECIFIC, 0>	cert;
  CertBag(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&certType);
    register_child(&cert);
  };
};

class EXPORTCLASS CRLBag : public asn_sequence {
public:
  asn_oid						crlType;
  asn_explicit<asn_any, CLASS_CONTEXT_SPECIFIC, 0>	crl;
  CRLBag(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&crlType);
    register_child(&crl);
  };
};

class EXPORTCLASS SecretBag : public asn_sequence {
public:
  asn_oid						secretType;
  asn_explicit<asn_any, CLASS_CONTEXT_SPECIFIC, 0>	secret;
  SecretBag(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&secretType);
    register_child(&secret);
  };
};

class EXPORTCLASS MacData : public asn_sequence {
public:
  DigestInfo		mac;
  asn_octetstring	macSalt;
  asn_integer		macIterationCount;
  check(unsigned char *data, unsigned int dataLen, unsigned char *pw, 
	unsigned int pwLen);
  MacData(security_t s = ASN_PUBLIC) : asn_sequence() {
    macIterationCount.set_default_value(1);
    register_child(&mac);
    register_child(&macSalt);
    register_child(&macIterationCount);
  };
};

class EXPORTCLASS PFX : public asn_sequence {
private:
  KeyList		keyList;
  CertList		certList;
  utf8String		friendlyName;
  SafeContents		sc;

public:
  asn_integer		version;
  ContentInfo		authSafes;
  MacData		macData;
  uint32		read(unsigned char *pw, r_buffer_t &buf);
  uint32		write(unsigned char *pw, buffer_t &buf);
  uint32		add_cert(const x509_certificate *cert);
  uint32		get_certs(CertList &cl);
  uint32		add_key(const PrivateKeyInfo *key);
  uint32		get_keys(KeyList &kl);
  uint32		set_friendly_name(utf8String name);
  uint32		get_friendly_name(utf8String &name);
  uint32		read_file(const utf8String file, 
				  const utf8String pass);
  uint32		write_file(const utf8String file,
				   const utf8String pass);

  PFX(security_t s = ASN_PUBLIC) : asn_sequence() {
    macData.set_optional();
    register_child(&version);
    register_child(&authSafes);
    register_child(&macData);
  };
};

class EXPORTCLASS CertificationRequestInfo : public asn_sequence {
public:
  asn_integer						version;
  asn_x500name						subject;
  SubjectPublicKeyInfo				subjectPublicKeyInfo;
  asn_implicit<Attributes, CLASS_CONTEXT_SPECIFIC, 0>	attributes;
  CertificationRequestInfo(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&version);
    register_child(&subject);
    register_child(&subjectPublicKeyInfo);
    register_child(&attributes);
  };
};

class CertificationRequest : public asn_sequence { 
public:
  CertificationRequestInfo	certificationRequestInfo;
  AlgorithmIdentifier		signatureAlgorithm;
  asn_bitstring				signature;
  CertificationRequest(security_t s = ASN_PUBLIC) : asn_sequence() {
    register_child(&certificationRequestInfo);
    register_child(&signatureAlgorithm);
    register_child(&signature);
  };
};

#endif
