This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author debatem1
Recipients daniel.urban, debatem1, eric.araujo, exarkun, gdamjan, giampaolo.rodola, gregory.p.smith, heikki, jsamuel, loewis, mcrute, pitrou
Date 2010-06-20.06:30:39
SpamBayes Score 1.3863082e-05
Marked as misclassified No
Message-id <AANLkTil6RDoE6R9ZMUrLkfuFpDhS7XklDz4vJcYnQxRv@mail.gmail.com>
In-reply-to <1276948348.3371.0.camel@localhost.localdomain>
Content
On Sat, Jun 19, 2010 at 7:52 AM, Antoine Pitrou <report@bugs.python.org> wrote:
>
> Antoine Pitrou <pitrou@free.fr> added the comment:
>
> Le samedi 19 juin 2010 à 00:55 +0000, geremy condra a écrit :
>> geremy condra <debatem1@gmail.com> added the comment:
>>
>> On Fri, Jun 18, 2010 at 6:05 AM, Antoine Pitrou <report@bugs.python.org> wrote:
>> >
>> > Antoine Pitrou <pitrou@free.fr> added the comment:
>> >
>> >> Great, I'm thinking more-or-less the API proposed in PEP 272- the
>> >> exception I'm thinking of is that 'strings' should be substituted for
>> >> 'bytes'- for AES and DES. It gets trickier when talking about public
>> >> key crypto, though. Perhaps something along the lines of
>> >> RSA.new(public_key=None, private_key=None,...), with the resulting
>> >> object supporting encrypt/decrypt/sign/verify operations?
>> >
>> > I don't have any opinion right now. I think a concrete proposal should
>> > be initiated and we can iterate from that.
>> > (that's assuming other people agree on the principle, of course)
>>
>> I assume that by "a concrete proposal" you're talking about code? Or
>> API docs? Also, what more needs to be done to ensure that other people
>> agree on the principle?
>
> I was thinking about a PEP. Of course, you are free to reuse existing
> PEP content for that :)

Ok. I've gone ahead and put together kind of a map for what I think the
basic structure of the library is going to look like. Let me know what you
think, and once we're done with that we can proceed into PEP land.

crypto API
==========
Variables message, key, salt, iv, ciphertext, and signature are of type bytes.
Variables public_key and private_key are DER-encoded bytes.
Variable bitlength is an integer.

Note that we deviate from the standard in PEP 272 in several ways:

	* arguments are generally bytes rather than strings
	* ciphers do not accept the 'counter', 'rounds', or 'segment_size' args

Layer 1
-------

Symmetric Ciphers
	crypto.cipher.encrypt(message, key) -> (salt, iv, ciphertext)
		depends on:
			crypto.keys.strengthen_password
			crypto.AES.new
			crypto.AES.encrypt
		raises:
			crypto.cipher.EncryptionError

	crypto.cipher.decrypt(salt, iv, ciphertext, key) -> message
		depends on:
			crypto.AES.new
			crypto.AES.decrypt
		raises:
			crypto.cipher.DecryptionError

Envelope Encryption
	crypto.envelope.encrypt(message, public_key) -> (iv, aes_key, ciphertext)
		depends on:
			crypto.keys.random_key
			crypto.AES.new
			crypto.AES.encrypt
			crypto.RSA.new
			crypto.RSA.encrypt
		raises:
			crypto.envelope.EncryptionError

	crypto.envelope.decrypt(iv, aes_key, ciphertext, private_key) -> message
		depends on:
			crypto.AES.new
			crypto.AES.decrypt
			crypto.RSA.new
			crypto.RSA.decrypt
		raises:
			crypto.envelope.DecryptionError

Digital Signatures
	crypto.signature.sign(message, private_key) -> signature
		depends on:
			hashlib.SHA512.new
			hashlib.SHA512.update
			hashlib.SHA512.digest
			crypto.RSA.new
			crypto.RSA.sign
		raises:
			crypto.signature.SigningError

	crypto.signature.verify(message, signature, public_key)
		depens on:
			hashlib.SHA512.new
			hashlib.SHA512.update
			hashlib.SHA512.digest
			crypto.RSA.new
			crypto.RSA.verify

Layer 2
-------

Utilities
	crypto.keys.strengthen_password(password) -> key
		depends on:
			openssl: RAND_bytes, EVP_get_digest_by_name, EVP_bytes_to_key
		raises:
			crypto.keys.KeyGenerationError

Symmetric Encryption
	crypto._cipher_object

		crypto._cipher_object.CipherObject._ctx = openssl context | None
		crypto._cipher_object.CipherObject._cipher = openssl cipher | None
		crypto._cipher_object.CipherObject._key = bytes | None

		CipherObject.encrypt(self, data) -> ciphertext
			depends on:
				crypto._cipher_object.CipherObject.encrypt_init
				crypto._cipher_object.CipherObject.encrypt_update
				crypto._cipher_object.CipherObject.encrypt_finalize
			raises:
				crypto._cipher_object.EncryptError

		CipherObject.encrypt_init() -> None
			depends on:
				openssl: EVP_EncryptInit_ex
			raises:
				crypto._cipher_object.EncryptInitError

		CipherObject.encrypt_update
			depends on:
				openssl: EVP_EncryptUpdate_ex
			raises:
				crypto._cipher_object.EncryptUpdateError

		CipherObject.encrypt_finalize
			depends on:
				openssl: EVP_EncryptFinal_ex
			raises:
				crypto._cipher_object.FinalizeError

		CipherObject.decrypt(self, ciphertext) -> message
			depends on:
				crypto._cipher_object.CipherObject.decrypt_init
				crypto._cipher_object.CipherObject.decrypt_update
				crypto._cipher_object.CipherObject.decrypt_finalize
			raises:
				crypto._cipher_object.DecryptError

		CipherObject.decrypt_init() -> None
			depends on:
				openssl: EVP_DecryptInit_ex
			raises:
				crypto._cipher_object.DecryptInitError

		CipherObject.decrypt_update
			depends on:
				openssl: EVP_DecryptUpdate_ex
			raises:
				crypto._cipher_object.DecryptUpdateError

		CipherObject.decrypt_finalize
			depends on:
				openssl: EVP_DecryptFinal_ex
			raises:
				crypto._cipher_object.DecryptFinalizeError

	crypto.AES
		crypto.AES.new(key, mode, IV=None) -> cipher_object

	crypto.DES
		crypto.DES.new(key, mode, IV=None) -> cipher_object

Asymmetric Encryption
	crypto.RSA
		crypto.RSA.new(public_key=None, private_key=None, padding=4) -> crypto.RSA.RSA
			depends on:
				openssl: d2i_RSAPublicKey, d2i_RSAPrivateKey
			raises:
				crypto.RSA.KeyError
				crypto.RSA.InitializationError

		crypto.RSA.generate_keypair(bitlength) -> public_key, private_key
			depends on:
				openssl: RSA_generate_key, i2d_RSAPublicKey, RSA_free
			raises:
				crypto.RSA.KeygenError

	crypt.RSA.RSA
		crypto.RSA.RSA._public_key = openssl RSA key | None
		crypto.RSA.RSA._private_key = openssl RSA key | None
		crypto.RSA.RSA._padding_type = integer

		crypto.RSA.RSA.encrypt(self, data) -> ciphertext
			depends on:
				openssl: RSA_size, RSA_public_encrypt
			raises:
				crypto.RSA.EncryptionError

		crypto.RSA.RSA.decrypt(self, ciphertext) -> message
			depends on:
				openssl: RSA_size, RSA_private_decrypt
			raises:
				crypto.RSA.DecryptionError

		crypto.RSA.RSA.sign(self, hash) -> signature
			depends on:
				openssl: RSA_size, RSA_sign
			raises:
				crypto.RSA.SigningError

		crypto.RSA.RSA.verify(self, hash, signature) -> True | False
			depends on:
				openssl: RSA_size, RSA_verify
			raises:
				crypto.RSA.VerificationError

Geremy Condra
History
Date User Action Args
2010-06-20 06:30:46debatem1setrecipients: + debatem1, loewis, gregory.p.smith, exarkun, pitrou, giampaolo.rodola, gdamjan, heikki, eric.araujo, daniel.urban, mcrute, jsamuel
2010-06-20 06:30:43debatem1linkissue8998 messages
2010-06-20 06:30:39debatem1create