First public contribution.
2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
27 #include <mctkeystore.h>
35 class CASN1EncSequence;
36 class CPBEncryptParms;
39 * This class provides the means to encode PKCS#5 parameters
40 * into an ASN1 sequence as specified in the PKCS#5 specifications.
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.
51 * This class is used, for instance, by TASN1EncPKCS8 to specify the PBE
52 * parameters of encrypted private keys.
54 * @param aParms The PBE parameters to be encoded
56 * @return An ASN1 sequence encoding the given PBE parameters.
58 IMPORT_C static CASN1EncSequence* EncodeDERL(const CPBEncryptParms& aParms);
63 * This class provides the means to decode an ASN1 sequence encoding
64 * PKCS#5 PBE parameters.
71 * Decodes a ASN1 sequence encoding PKCS#5 PBE parameters.
72 * The ASN1 syntax is specified in the PKCS#5 v2.0 specifications.
74 * @param aBinaryData A descriptor containing the ASN1 data in binary format.
76 * @return The decoded PBE parameters.
78 IMPORT_C static CPBEncryptParms* DecodeDERL(const TDesC8& aBinaryData);
82 //! Converts stored key data and key info to PKCS8 and returns ASN1 encoding thereof
86 /// The minimum number of bytes necessary to determine that data is cleartext pkcs8
87 const TInt KIsPKCS8DataMinLength = 24;
89 /// The minimum number of bytes necessary to determine that data is encrypted pkcs8
90 const TInt KIsEncryptedPKCS8DataMinLength = 36;
93 * Provides the means to decode PKCS#8 encoded private keys.
100 * Decodes DER encoded ASN1 data representing a PKCS#8 clear text private key.
101 * See the PKCS#8 specifications for the ASN1 syntax.
103 * @param aBinaryData A descriptor containing the ASN1 data.
105 * @return A pointer to a CDecPKCS8Data object containing the decoded private key.
107 IMPORT_C static CDecPKCS8Data* DecodeDERL(const TDesC8& aBinaryData);
110 * Decodes DER encoded ASN1 data representing a PKCS#8 encrypted private key.
111 * See the PKCS#8 specifications for the ASN1 syntax.
113 * @param aBinaryData A descriptor containing the ASN1 data.
114 * @param aPassword The password to decrypt the key.
116 * @return A pointer to a CDecPKCS8Data object containing the decoded private key.
118 IMPORT_C static CDecPKCS8Data* DecodeEncryptedDERL(const TDesC8& aBinaryData, const TDesC8& aPassword);
121 * Determines if some binary data is a pkcs#8 clear text private key.
123 * @param aBinaryData A descriptor containing the data. This must be at
124 * least KIsPKCS8DataMinLength bytes long.
126 * @return ETrue if binary data is pkcs#8 clear text private key or EFalse if it is not.
128 IMPORT_C static TBool IsPKCS8Data(const TDesC8& aBinaryData);
131 * Determines if some binary data is an encrypted pkcs#8 private key.
133 * @param aBinaryData A descriptor containing the data.
135 * @return ETrue if binary data is an encrypted pkcs#8 private key or EFalse if it is not.
137 IMPORT_C static TBool IsEncryptedPKCS8Data(const TDesC8& aBinaryData);
140 static TBool IsASN1Sequence(const TDesC8& aBinaryData, TInt& aPos);
141 static TBool IsExpectedData(const TDesC8& aBinaryData, TInt& aPos, const TDesC8& aExpectedData);
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
151 //! PrivateKeyInfo ::= SEQUENCE {
153 //! privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
154 //! privateKey PrivateKey,
155 //! attributes [0] IMPLICIT Attributes OPTIONAL }
157 //! Version ::= INTEGER
158 //! PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
159 //! PrivateKey ::= OCTET STRING
160 //! Attributes ::= SET OF Attribute
162 class MPKCS8DecodedKeyPairData; // Forward declare
166 * This class provides the means to decode PKCS#8 encoded private keys.
169 class CDecPKCS8Data : public CBase
175 * Decodes a ASN1 sequence encoding PKCS#8 encrypted private key.
177 * @param aData A descriptor containing the data.
179 * @return A pointer to a CDecPKCS8Data object containing the decoded private key.
181 static CDecPKCS8Data* NewL(const TDesC8& aData);
187 virtual ~CDecPKCS8Data();
191 * Returns the version number of the certificate.
193 * @return Version number of the certificate.
195 inline TInt Version() const;
198 * Return the algorithm identifier.
200 * @return algorithm identifier.
202 inline TAlgorithmId Algorithm() const;
205 * Returns the key pair data. This depends on the value returned by CDecPKCS8Data::Algorithm()
207 * @return either RSA or DSA to M class key pair data.
209 inline MPKCS8DecodedKeyPairData* KeyPairData() const;
212 * Returns a DER-encoded set of PKCS8 attributes (use TASN1DecSet to decode)
214 * @return a PKCS8 attributes
216 inline const TDesC8& PKCS8Attributes() const;
219 /** @internalComponent */
221 /** @internalComponent */
222 void ConstructL(const TDesC8& aData);
224 private: // No copying
225 CDecPKCS8Data(const CDecPKCS8Data&);
226 CDecPKCS8Data& operator=(CDecPKCS8Data&);
230 TAlgorithmId iAlgorithmID;
231 MPKCS8DecodedKeyPairData* iKeyPairData;
236 //! Mixin class for generic actions to be performed on a keypair
239 class MPKCS8DecodedKeyPairData
243 * Gets a key identifier
245 * @param aKeyIdentifier A descriptor containing a key identifier (SHA1 hash of modulus)
247 virtual void GetKeyIdentifierL(TKeyIdentifier& aKeyIdentifier) const = 0;
248 virtual TUint KeySize() const = 0;
249 virtual void Release() = 0;
252 virtual ~MPKCS8DecodedKeyPairData();
256 class CRSAPrivateKey;
257 class TASN1DecGeneric;
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)
262 class CPKCS8KeyPairRSA : public CBase, public MPKCS8DecodedKeyPairData
268 * Constructs the ASN1 PKCS#8 RSA private key.
270 * @param aSource A descriptor containing the key identifier
272 * @return A pointer to a MPKCS8DecodedKeyPairData object containing the decoded private key.
274 static MPKCS8DecodedKeyPairData* NewL(const TASN1DecGeneric& aSource);
280 virtual ~CPKCS8KeyPairRSA();
284 * Gets a key identifier
286 * @param aKeyIdentifier A descriptor containing a key identifier
288 virtual void GetKeyIdentifierL(TKeyIdentifier& aKeyIdentifier) const;
289 virtual TUint KeySize() const;
290 virtual void Release();
293 * Contructs a RSA Public Key
295 * @return A RSA Public Key
297 inline const CRSAPublicKey& PublicKey() const;
300 * Contructs a RSA Private Key
302 * @return A RSA Private Key
304 inline const CRSAPrivateKey& PrivateKey() const;
308 /** @internalComponent */
309 void ConstructL(const TASN1DecGeneric& aSource);
312 CRSAPublicKey* iPublicKey;
313 CRSAPrivateKey* iPrivateKey;
318 class CDSAPrivateKey;
320 //! Represents a DSA key pair and provides the means to externalize it to
321 //! a stream and generate a key identifier
323 class CPKCS8KeyPairDSA : public CBase, public MPKCS8DecodedKeyPairData
329 * Contructs the ASN1 PKCS#8 DSA private key
331 * @param aParamsData A block of PKCS#8 parameters data for DER data to decode
333 * @param aSource A descriptor containing a key identifier
335 * @return A pointer to MPKCS8DecodedKeyPairData object containing the decoded key.
337 static MPKCS8DecodedKeyPairData* NewL(const TDesC8& aParamsData, const TASN1DecGeneric& aSource);
343 virtual ~CPKCS8KeyPairDSA();
347 * Gets a key identifier
349 * @param aKeyIdentifier A descriptor containing a key identifier
351 virtual void GetKeyIdentifierL(TKeyIdentifier& aKeyIdentifier) const;
352 virtual TUint KeySize() const;
353 virtual void Release();
356 * Contructs a DSA Public Key
358 * @return A DSA Public Key
360 inline const CDSAPublicKey& PublicKey() const;
363 * Contructs a RSA Private Key
365 * @return A RSA Private Key
367 inline const CDSAPrivateKey& PrivateKey() const;
371 /** @internalComponent */
372 void ConstructL(const TDesC8& aParamsData, const TASN1DecGeneric& aSource);
375 CDSAPublicKey* iPublicKey;
376 CDSAPrivateKey* iPrivateKey;
379 class CRSAPrivateKeyCRT;
380 class CASN1EncOctetString;
382 class CPBEncryptParms;
387 * Encodes the given private key using the pkcs#8 standard.
389 * The returned ASN1 sequence respects the following grammar:
391 * PrivateKeyInfo ::= SEQUENCE {
393 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
394 * privateKey PrivateKey,
395 * attributes [0] IMPLICIT Attributes OPTIONAL }
397 * Version ::= INTEGER
398 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
399 * PrivateKey ::= OCTET STRING
400 * Attributes ::= SET OF Attribute
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.
406 * Or, in the case of encrypted private keys:
408 * EncryptedPrivateKeyInfo ::= SEQUENCE {
409 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
410 * encryptedData EncryptedData }
412 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
413 * EncryptedData ::= OCTET STRING
415 * AlgorithmIdentifier is the ASN1 sequence defined in the
422 * Returns the ASN1 PKCS#8 encoding of a RSA private key.
424 * The private key syntax for this key type is defined in
425 * the PKCS#1 document. It follows the grammar:
427 * RSAPrivateKey ::= SEQUENCE {
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
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
446 * @return An ASN1 Sequence encoding the key.
448 IMPORT_C static CASN1EncSequence* EncodeL(const CRSAPrivateKeyCRT& aPrivateKey,
449 const CRSAPublicKey& aPublicKey, const TDesC8& attributes);
451 * Encodes an RSA key in encrypted format.
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
462 * @return An ASN1 Sequence encoding the encrypted key.
464 IMPORT_C static CASN1EncSequence* EncodeEncryptedL(const CRSAPrivateKeyCRT& aPrivateKey,
465 const CRSAPublicKey& aPublicKey,
466 CPBEncryptor& aEncryptor,
467 CPBEncryptParms& aData, const TDesC8& attributes);
470 * Returns the ASN1 PKCS#8 encoding of a DSA private key.
472 * The private key syntax for this key type is defined in
473 * the PKCS#11 document.
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
480 * @return An ASN1 Sequence encoding the key.
482 IMPORT_C static CASN1EncSequence* EncodeL(const CDSAPrivateKey& aPrivateKey, const TDesC8& attributes);
485 * Encodes a DSA key in encrypted format.
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.
493 * @return An ASN1 Sequence encoding the encrypted key.
495 IMPORT_C static CASN1EncSequence* EncodeEncryptedL(const CDSAPrivateKey& aPrivateKey,
496 CPBEncryptor& aEncryptor,
497 CPBEncryptParms& aData,
498 const TDesC8& attributes);
503 * Converts the ASN1 element to an octet string.
505 * @param aAsnElement The ASN1 element to be converted
507 * @return An ASN1 Octet string representing the input element.
509 static CASN1EncOctetString* ElementToOctetL(CASN1EncBase& aAsnElement);
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.
516 * @param aKeySeq The key sequence to be encrypted.
517 * @param aEncryptor The CPBEncryptor object used to encrypt the given key.
519 * @return An ASN1 octet string containing the encrypted key.
521 static CASN1EncOctetString* EncryptKeySequenceL(CASN1EncSequence& aKeySeq,
522 CPBEncryptor& aEncryptor);
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.
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.
537 * @return An ASN1 sequence of type EncryptedPrivateKeyInfo.
539 static CASN1EncSequence* EncryptedSequenceL(CASN1EncSequence& aPrivateKeySequence,
540 CPBEncryptor& aEncryptor,
541 CPBEncryptParms& aData);
544 * Given a CRT RSA private key it calculates the RSA private exponent "d".
546 * @param aPrivateKey The RSA private key in CRT format we are interested in.
547 * @param aPublicKey The RSA public key
549 * @return The RSA private exponent "d".
551 static const RInteger CalculateRSAPrivExpL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey);
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.
559 * @param aAttribute The DER encoded ASN1 structure.
560 * @param aSeq The sequence to which we want to add the attributes.
562 static void AddAttributesL(CASN1EncSequence& aSeq, const TDesC8& aAttribute);
565 // Inline function definition //
567 inline TInt CDecPKCS8Data::Version() const
572 inline TAlgorithmId CDecPKCS8Data::Algorithm() const
574 return (iAlgorithmID);
577 inline MPKCS8DecodedKeyPairData* CDecPKCS8Data::KeyPairData() const
579 return (iKeyPairData);
583 inline const TDesC8& CDecPKCS8Data::PKCS8Attributes() const
586 return (*iAttributes);
591 inline const CRSAPublicKey& CPKCS8KeyPairRSA::PublicKey() const
596 inline const CRSAPrivateKey& CPKCS8KeyPairRSA::PrivateKey() const
601 inline const CDSAPublicKey& CPKCS8KeyPairDSA::PublicKey() const
606 inline const CDSAPrivateKey& CPKCS8KeyPairDSA::PrivateKey() const
613 #endif // __ASNPKCS_H__