os/security/cryptoservices/asnpkcs/inc/asnpkcs.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #ifndef __ASNPKCS_H__
    20 #define __ASNPKCS_H__
    21 
    22 #include <e32std.h>
    23 #include <e32base.h>
    24 #include <s32file.h>
    25 #include <signed.h>
    26 #include <x509cert.h>
    27 #include <mctkeystore.h>
    28 
    29 /**
    30  * @file
    31  * @publishedPartner 
    32  * @released
    33  */
    34 
    35 class CASN1EncSequence;
    36 class CPBEncryptParms;
    37 
    38 /**
    39  * This class provides the means to encode PKCS#5 parameters 
    40  * into an ASN1 sequence as specified in the PKCS#5 specifications.
    41  * 
    42  */
    43 class TASN1EncPKCS5
    44 	{
    45 public:
    46 	/**
    47 	 * Returns an ASN1 sequence encoding the given PKCS#5 PBE parameters.
    48 	 * The ASN1 syntax used is specified in the PKCS#5 v2.0  specifications. 
    49 	 * Refer to the specs for a detailed description of the returned sequence.
    50 	 *
    51 	 * This class is used, for instance, by TASN1EncPKCS8 to specify the PBE
    52 	 * parameters of encrypted private keys.
    53 	 *
    54 	 * @param aParms The PBE parameters to be encoded
    55 	 *
    56 	 * @return An ASN1 sequence encoding the given PBE parameters.
    57 	 */
    58 	IMPORT_C static CASN1EncSequence* EncodeDERL(const CPBEncryptParms& aParms);
    59 	};
    60 
    61 
    62 /**
    63  * This class provides the means to decode an ASN1 sequence encoding
    64  * PKCS#5 PBE parameters.
    65  * 
    66  */
    67 class TASN1DecPKCS5
    68 	{
    69 public:
    70 	/**
    71 	 * Decodes a ASN1 sequence encoding PKCS#5 PBE parameters.
    72 	 * The ASN1 syntax is specified in the PKCS#5 v2.0  specifications.
    73 	 *
    74 	 * @param aBinaryData A descriptor containing the ASN1 data in binary format.
    75 	 *
    76 	 * @return The decoded PBE parameters.
    77 	 */
    78 	IMPORT_C static CPBEncryptParms* DecodeDERL(const TDesC8& aBinaryData);
    79 	};
    80 
    81 //!
    82 //!	Converts stored key data and key info to PKCS8 and returns ASN1 encoding thereof
    83 //!	
    84 class CDecPKCS8Data;
    85 
    86 /// The minimum number of bytes necessary to determine that data is cleartext pkcs8
    87 const TInt KIsPKCS8DataMinLength = 24;
    88 
    89 /// The minimum number of bytes necessary to determine that data is encrypted pkcs8
    90 const TInt KIsEncryptedPKCS8DataMinLength = 36;
    91 
    92 /**
    93  * Provides the means to decode PKCS#8 encoded private keys.
    94  * 
    95  */
    96 class TASN1DecPKCS8
    97 	{
    98 public:
    99 	/**
   100 	 * Decodes DER encoded ASN1 data representing a PKCS#8 clear text private key.
   101 	 * See the PKCS#8 specifications for the ASN1 syntax.
   102 	 *
   103 	 * @param aBinaryData A descriptor containing the ASN1 data.
   104 	 *
   105 	 * @return A pointer to a CDecPKCS8Data object containing the decoded private key.
   106 	 */
   107 	IMPORT_C static CDecPKCS8Data* DecodeDERL(const TDesC8& aBinaryData);
   108 
   109 	/**
   110 	 * Decodes DER encoded ASN1 data representing a PKCS#8 encrypted  private key.
   111 	 * See the PKCS#8 specifications for the ASN1 syntax.
   112 	 *
   113 	 * @param aBinaryData A descriptor containing the ASN1 data.
   114 	 * @param aPassword The password to decrypt the key.
   115 	 *
   116 	 * @return A pointer to a CDecPKCS8Data object containing the decoded private key.
   117 	 */
   118 	IMPORT_C static CDecPKCS8Data* DecodeEncryptedDERL(const TDesC8& aBinaryData, const TDesC8& aPassword);
   119 
   120 	/**
   121 	 * Determines if some binary data is a pkcs#8 clear text private key.
   122 	 * 
   123 	 * @param aBinaryData A descriptor containing the data.  This must be at
   124 	 * least KIsPKCS8DataMinLength bytes long.
   125 	 *
   126 	 * @return ETrue if binary data is pkcs#8 clear text private key or EFalse if it is not.
   127 	 */
   128 	IMPORT_C static TBool IsPKCS8Data(const TDesC8& aBinaryData);
   129 
   130 	/**
   131 	 * Determines if some binary data is an encrypted pkcs#8 private key.
   132 	 * 
   133 	 * @param aBinaryData A descriptor containing the data.
   134 	 *
   135 	 * @return ETrue if binary data is an encrypted pkcs#8 private key or EFalse if it is not.
   136 	 */
   137 	IMPORT_C static TBool IsEncryptedPKCS8Data(const TDesC8& aBinaryData);
   138 
   139 private:
   140 	static TBool IsASN1Sequence(const TDesC8& aBinaryData, TInt& aPos);
   141 	static TBool IsExpectedData(const TDesC8& aBinaryData, TInt& aPos, const TDesC8& aExpectedData);
   142 };
   143 	
   144 
   145 //!
   146 //!	Server side object decodes a PKCS8 data object incoming from client
   147 //!	On construction, decodes the data to determine version, key
   148 //!	algorithm and gives access to the key data by creating the appropriate
   149 //!	MPKCS8DecodedKeyPairData object for the algorithm
   150 //!	
   151 //!	PrivateKeyInfo ::= SEQUENCE {
   152 //!	version Version,
   153 //!	privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
   154 //!	privateKey PrivateKey,
   155 //!	attributes [0] IMPLICIT Attributes OPTIONAL }
   156 //!	
   157 //!	Version ::= INTEGER
   158 //!	PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
   159 //!	PrivateKey ::= OCTET STRING
   160 //!	Attributes ::= SET OF Attribute
   161 //!
   162 class MPKCS8DecodedKeyPairData;	//	Forward declare
   163 
   164 
   165 /**
   166  * This class provides the means to decode PKCS#8 encoded private keys.
   167  * 
   168  */
   169 class CDecPKCS8Data : public CBase
   170 {
   171 public:
   172 	/**
   173 	 * @internalComponent
   174 	 * 
   175 	 * Decodes a ASN1 sequence encoding PKCS#8 encrypted  private key.
   176 	 *
   177 	 * @param aData A descriptor containing the data.
   178 	 *
   179 	 * @return A pointer to a CDecPKCS8Data object containing the decoded private key.
   180 	 */
   181 	static CDecPKCS8Data* NewL(const TDesC8& aData);
   182 	
   183 public:
   184 	/** 
   185      * Destructor
   186      */
   187 	virtual ~CDecPKCS8Data();
   188 	
   189 public:
   190 	/*
   191 	 * Returns the version number of the certificate.
   192 	 *
   193 	 * @return Version number of the certificate.
   194 	 */
   195 	inline TInt Version() const;
   196 	
   197 	/*
   198 	 * Return the algorithm identifier.
   199 	 *
   200 	 * @return algorithm identifier.
   201 	 */
   202 	inline TAlgorithmId Algorithm() const;
   203 	
   204 	/*
   205 	 * Returns the key pair data. This depends on the value returned by CDecPKCS8Data::Algorithm()
   206 	 *
   207 	 * @return either RSA or DSA to M class key pair data. 
   208 	 */
   209 	inline MPKCS8DecodedKeyPairData* KeyPairData() const;
   210 	
   211 	/*
   212 	 * Returns a DER-encoded set of PKCS8 attributes (use TASN1DecSet to decode)
   213 	 *
   214 	 * @return a PKCS8 attributes
   215 	 */
   216 	inline const TDesC8& PKCS8Attributes() const;
   217 	
   218 protected:
   219 	/** @internalComponent */
   220 	CDecPKCS8Data();
   221 	/** @internalComponent */
   222 	void ConstructL(const TDesC8& aData);
   223 	
   224 private:	//	No copying
   225 	CDecPKCS8Data(const CDecPKCS8Data&);
   226 	CDecPKCS8Data& operator=(CDecPKCS8Data&);
   227 	
   228 private:
   229 	TInt iVersion;
   230 	TAlgorithmId iAlgorithmID;
   231 	MPKCS8DecodedKeyPairData* iKeyPairData;
   232 	HBufC8* iAttributes;
   233 };
   234 
   235 
   236 //!	Mixin class for generic actions to be performed on a keypair
   237 //!	
   238 //!
   239 class MPKCS8DecodedKeyPairData
   240 {
   241 public:
   242 	/** 
   243 	 * Gets a key identifier
   244 	 *
   245      * @param aKeyIdentifier A descriptor containing a key identifier (SHA1 hash of modulus)
   246      */
   247 	virtual void GetKeyIdentifierL(TKeyIdentifier& aKeyIdentifier) const = 0;
   248 	virtual TUint KeySize() const = 0;	
   249 	virtual void Release() = 0;
   250 	
   251 protected:
   252 	virtual ~MPKCS8DecodedKeyPairData();
   253 };
   254 
   255 class CRSAPublicKey;
   256 class CRSAPrivateKey;
   257 class TASN1DecGeneric;
   258 
   259 //!	Represents an RSA key pair and provides the means to externalize it to
   260 //!	a stream and generate a key identifier (SHA1 hash of modulus)
   261 //!
   262 class CPKCS8KeyPairRSA : public CBase, public MPKCS8DecodedKeyPairData
   263 {
   264 public:
   265 	/**
   266 	 * @internalComponent
   267 	 *
   268 	 * Constructs the ASN1 PKCS#8 RSA private key.	 
   269  	 *
   270  	 * @param aSource A descriptor containing the key identifier
   271  	 *
   272  	 * @return A pointer to a MPKCS8DecodedKeyPairData object containing the decoded private key.
   273 	 */ 
   274 	static MPKCS8DecodedKeyPairData* NewL(const TASN1DecGeneric& aSource);
   275 	
   276 public:
   277 	/** 
   278      * Destructor
   279      */
   280 	virtual ~CPKCS8KeyPairRSA();
   281 	
   282 public:
   283 	/** 
   284 	 * Gets a key identifier
   285 	 *
   286      * @param aKeyIdentifier A descriptor containing a key identifier
   287      */
   288 	virtual void GetKeyIdentifierL(TKeyIdentifier& aKeyIdentifier) const;	
   289 	virtual TUint KeySize() const;	
   290 	virtual void Release();
   291 	
   292 	/** 
   293 	 * Contructs a RSA Public Key
   294 	 *
   295  	 * @return A RSA Public Key
   296      */
   297 	inline const CRSAPublicKey& PublicKey() const;
   298 		
   299 	/** 
   300 	 * Contructs a RSA Private Key
   301 	 *
   302  	 * @return A RSA Private Key
   303      */
   304 	inline const CRSAPrivateKey& PrivateKey() const;
   305 	
   306 protected:
   307 	CPKCS8KeyPairRSA(){}	
   308 	/** @internalComponent */
   309 	void ConstructL(const TASN1DecGeneric& aSource);
   310 	
   311 private:
   312 	CRSAPublicKey* iPublicKey;
   313 	CRSAPrivateKey* iPrivateKey;
   314 };
   315 
   316 
   317 class CDSAPublicKey;
   318 class CDSAPrivateKey;
   319 
   320 //!	Represents a DSA key pair and provides the means to externalize it to
   321 //!	a stream and generate a key identifier
   322 //!
   323 class CPKCS8KeyPairDSA : public CBase, public MPKCS8DecodedKeyPairData
   324 {
   325 public:
   326 	/** 
   327 	 * @internalComponent
   328 	 * 
   329 	 * Contructs the ASN1 PKCS#8 DSA private key
   330 	 *
   331 	 * @param aParamsData A block of PKCS#8 parameters data for DER data to decode
   332 	 *
   333 	 * @param aSource A descriptor containing a key identifier		
   334 	 *
   335 	 * @return A pointer to MPKCS8DecodedKeyPairData object containing the decoded key.
   336 	 */
   337 	static MPKCS8DecodedKeyPairData* NewL(const TDesC8& aParamsData, const TASN1DecGeneric& aSource);
   338 	
   339 public:
   340 	/** 
   341      * Destructor
   342      */
   343 	virtual ~CPKCS8KeyPairDSA();
   344 	
   345 public:
   346 	/** 
   347 	 * Gets a key identifier
   348 	 *
   349      * @param aKeyIdentifier A descriptor containing a key identifier
   350      */
   351 	virtual void GetKeyIdentifierL(TKeyIdentifier& aKeyIdentifier) const;
   352 	virtual TUint KeySize() const;
   353 	virtual void Release();
   354 	
   355 	/** 
   356 	 * Contructs a DSA Public Key
   357 	 *
   358  	 * @return A DSA Public Key
   359      */	
   360 	inline const CDSAPublicKey& PublicKey() const;
   361 	
   362 	/** 
   363 	 * Contructs a RSA Private Key
   364 	 *
   365  	 * @return A RSA Private Key
   366      */	
   367 	inline const CDSAPrivateKey& PrivateKey() const;
   368 	
   369 protected:
   370 	CPKCS8KeyPairDSA(){}
   371 	/** @internalComponent */
   372 	void ConstructL(const TDesC8& aParamsData, const TASN1DecGeneric& aSource);
   373 	
   374 private:
   375 	CDSAPublicKey* iPublicKey;
   376 	CDSAPrivateKey* iPrivateKey;
   377 };
   378 
   379 class CRSAPrivateKeyCRT;
   380 class CASN1EncOctetString;
   381 class CASN1EncBase;
   382 class CPBEncryptParms;
   383 class CPBEncryptor; 
   384 class RInteger;
   385 
   386 /**
   387  * Encodes the given private key using the pkcs#8 standard.
   388  *
   389  * The returned ASN1 sequence respects the following grammar:
   390  * 
   391  *	PrivateKeyInfo ::= SEQUENCE {
   392  *	version Version,
   393  *	privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
   394  *	privateKey PrivateKey,
   395  *	attributes [0] IMPLICIT Attributes OPTIONAL }
   396  *	
   397  *	Version ::= INTEGER
   398  *	PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
   399  *	PrivateKey ::= OCTET STRING
   400  *	Attributes ::= SET OF Attribute
   401  *
   402  * The PrivateKeyAlgorithmIdentifier format it depends on the 
   403  * specific algorithm it represents. For RSA is specified in 
   404  * the PKCS#1 document, for DSA in PKCS#11.
   405  *
   406  * Or, in the case of encrypted private keys:
   407  *
   408  *	EncryptedPrivateKeyInfo ::= SEQUENCE {
   409  *	encryptionAlgorithm EncryptionAlgorithmIdentifier,
   410  *	encryptedData EncryptedData }
   411  *	
   412  *	EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
   413  *	EncryptedData ::= OCTET STRING
   414  *
   415  * AlgorithmIdentifier is the ASN1 sequence defined in the
   416  * PKCS#5 standard. 
   417  */	
   418 class TASN1EncPKCS8
   419 	{
   420 public:
   421 	/**
   422 	 * Returns the ASN1 PKCS#8 encoding of a RSA private key.
   423 	 *
   424 	 * The private key syntax for this key type is defined in 
   425 	 * the PKCS#1 document. It follows the grammar:
   426 	 *
   427 	 * RSAPrivateKey ::= SEQUENCE {
   428 	 *   version Version,
   429 	 *   modulus INTEGER, -- n
   430 	 *   publicExponent INTEGER, -- e
   431 	 *	 privateExponent INTEGER, -- d
   432 	 *	 prime1 INTEGER, -- p
   433 	 *	 prime2 INTEGER, -- q
   434 	 *	 exponent1 INTEGER, -- d mod (p-1)
   435 	 *	 exponent2 INTEGER, -- d mod (q-1)
   436 	 *	 coefficient INTEGER, -- (inverse of q) mod p
   437 	 *	 otherPrimeInfos OtherPrimeInfos OPTIONAL
   438  	 *	}
   439  	 *
   440  	 * @param aPrivateKey The private key to be encoded (must be in CRT format)
   441  	 * @param aPublicKey The corresponding public key.
   442  	 * @param attributes A set of attributes of the extended information
   443  	 * 					 that is encrypted along with the private-key
   444  	 *					 information.
   445 	 *
   446  	 * @return An ASN1 Sequence encoding the key.
   447 	 */
   448 	IMPORT_C static CASN1EncSequence* EncodeL(const CRSAPrivateKeyCRT& aPrivateKey,
   449 	                                          const CRSAPublicKey& aPublicKey, const TDesC8& attributes);
   450 	/**
   451 	 * Encodes an RSA key in encrypted format.
   452 	 * 
   453  	 * @param aPrivateKey The private key to be encoded (must be in CRT format)
   454  	 * @param aPublicKey The corresponding public key.
   455 	 * @param aEncryptor The object used to encrypt the data.
   456 	 * @param aData The encryption parameters of the given encryptor.
   457 	 *              These parameters are stored in the resulting sequence.
   458  	 * @param attributes A set of attributes of the extended information
   459  	 * 					 that is encrypted along with the private-key
   460  	 *					 information.
   461 	 *
   462  	 * @return An ASN1 Sequence encoding the encrypted key.
   463 	 */
   464 	IMPORT_C static CASN1EncSequence* EncodeEncryptedL(const CRSAPrivateKeyCRT& aPrivateKey, 
   465 	                                                   const CRSAPublicKey& aPublicKey, 
   466 	                                                   CPBEncryptor& aEncryptor, 
   467 	                                                   CPBEncryptParms& aData, const TDesC8& attributes);
   468 
   469 	/**
   470 	 * Returns the ASN1 PKCS#8 encoding of a DSA private key.
   471 	 *
   472 	 * The private key syntax for this key type is defined in 
   473 	 * the PKCS#11 document. 
   474 	 *
   475  	 * @param aPrivateKey The private key to be encoded 
   476  	 * @param attributes A set of attributes of the extended information
   477  	 * 					 that is encrypted along with the private-key
   478  	 *					 information.
   479 	 *
   480  	 * @return An ASN1 Sequence encoding the key.
   481 	 */
   482 	IMPORT_C static CASN1EncSequence* EncodeL(const CDSAPrivateKey& aPrivateKey, const TDesC8& attributes);
   483 
   484 	/**
   485 	 * Encodes a DSA key in encrypted format.
   486 	 * 
   487  	 * @param aPrivateKey The private key to be encoded.
   488 	 * @param aEncryptor The object used to encrypt the data.
   489 	 * @param aData The encryption parameters of the given encryptor.
   490 	 *              These parameters are stored in the resulting sequence.
   491  	 * @param attributes
   492 	 *
   493  	 * @return An ASN1 Sequence encoding the encrypted key.
   494 	 */
   495 	IMPORT_C static CASN1EncSequence* EncodeEncryptedL(const CDSAPrivateKey& aPrivateKey, 
   496 	                                                   CPBEncryptor& aEncryptor, 
   497 	                                                   CPBEncryptParms& aData,
   498 							  const TDesC8& attributes);
   499 
   500 private:
   501 	/**
   502 	 *
   503 	 * Converts the ASN1 element to an octet string.
   504 	 *
   505 	 * @param aAsnElement The ASN1 element to be converted
   506 	 * 
   507 	 * @return An ASN1 Octet string representing the input element.
   508 	 */
   509  	static CASN1EncOctetString* ElementToOctetL(CASN1EncBase& aAsnElement);
   510 
   511 	/**
   512  	 * Given a ASN1 sequence representing a private key and a CPBEncryptor object,
   513  	 * it returns an ASN1 octet string containing the key sequence encrypted by
   514  	 * the given encryptor.
   515  	 *
   516  	 * @param aKeySeq The key sequence to be encrypted.
   517   	 * @param aEncryptor The CPBEncryptor object used to encrypt the given key.
   518 	 *
   519 	 * @return An ASN1 octet string containing the encrypted key.
   520  	 */
   521 	static CASN1EncOctetString* EncryptKeySequenceL(CASN1EncSequence& aKeySeq, 
   522 	                                                CPBEncryptor& aEncryptor);
   523 
   524 	/**
   525 	 *
   526 	 * Given a valid key sequence and appropriate PBE encryptors it 
   527 	 * encrypts the key and creates a PKCS#8 sequence of type
   528 	 * EncryptedPrivateKeyInfo.
   529 	 *
   530 	 * @param aPrivateKeySequence A ASN1 sequence of the private key to be 
   531 	 *                            encrypted. Generally the structure of the
   532 	 *                            sequence will depend on the key type.
   533 	 * @param aEncryptor The PBE encryptor to be used to encrypt the key.
   534 	 * @param aData The PBE encryptor parameters. This information must be 
   535 	 *              included in the final ASN1 sequence.
   536 	 *
   537 	 * @return An ASN1 sequence of type EncryptedPrivateKeyInfo.
   538 	 */
   539 	static CASN1EncSequence* EncryptedSequenceL(CASN1EncSequence& aPrivateKeySequence, 
   540                                                     CPBEncryptor& aEncryptor, 
   541                                                     CPBEncryptParms& aData);
   542 
   543 	/**
   544 	* Given a CRT RSA private key it calculates the RSA private exponent "d".
   545 	*
   546 	* @param aPrivateKey The RSA private key in CRT format we are interested in.
   547 	* @param aPublicKey The RSA public key
   548 	*
   549 	* @return The RSA private exponent "d".
   550 	*/                                                    
   551     static const RInteger CalculateRSAPrivExpL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey);
   552 
   553 	/**
   554 	 * Adds the given DER encoded ASN1 structure to the given sequence. If the structure is KNullDesC8
   555 	 * nothing is added. This method is used by the encoder to add the optional pkcs8 attributes to 
   556 	 * the ASN1 pkcs8 key it generates. PKCS8 attributes are stored as uninterpreted DER encoded
   557 	 * binary data in the keystore.
   558 	 *
   559 	 * @param aAttribute The DER encoded ASN1 structure.
   560 	 * @param aSeq The sequence to which we want to add the attributes.
   561 	 */
   562 	static void AddAttributesL(CASN1EncSequence& aSeq, const TDesC8& aAttribute);
   563 	};
   564 
   565 // Inline function definition //
   566 
   567 inline TInt CDecPKCS8Data::Version() const 
   568 	{
   569 	return (iVersion);
   570 	}
   571 
   572 inline TAlgorithmId CDecPKCS8Data::Algorithm() const 
   573 	{
   574 	return (iAlgorithmID);
   575 	}
   576 
   577 inline MPKCS8DecodedKeyPairData* CDecPKCS8Data::KeyPairData() const 
   578 	{
   579 	return (iKeyPairData);
   580 	}
   581 
   582 
   583 inline const TDesC8& CDecPKCS8Data::PKCS8Attributes() const 
   584 	{
   585 	if (iAttributes)
   586 		return (*iAttributes);
   587 	else
   588 		return (KNullDesC8);
   589 	}	
   590 
   591 inline const CRSAPublicKey& CPKCS8KeyPairRSA::PublicKey() const
   592 	{
   593 	return *iPublicKey;
   594 	}
   595 
   596 inline const CRSAPrivateKey& CPKCS8KeyPairRSA::PrivateKey() const
   597 	{
   598 	return *iPrivateKey;
   599 	}
   600 
   601 inline const CDSAPublicKey& CPKCS8KeyPairDSA::PublicKey() const
   602 	{
   603 	return *iPublicKey;
   604 	}
   605 
   606 inline const CDSAPrivateKey& CPKCS8KeyPairDSA::PrivateKey() const
   607 	{
   608 	return *iPrivateKey;
   609 	}
   610 
   611 
   612 
   613 #endif	//	__ASNPKCS_H__