Merge pull request #596 from reaperhulk/docs-test-vectors

Add test vector information to the development section
diff --git a/cryptography/fernet.py b/cryptography/fernet.py
index c19309d..71a9fad 100644
--- a/cryptography/fernet.py
+++ b/cryptography/fernet.py
@@ -22,8 +22,8 @@
 from cryptography.exceptions import InvalidSignature
 from cryptography.hazmat.backends import default_backend
 from cryptography.hazmat.primitives import padding, hashes
-from cryptography.hazmat.primitives.hmac import HMAC
 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+from cryptography.hazmat.primitives.hmac import HMAC
 
 
 class InvalidToken(Exception):
diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py
index 49a4014..4de0202 100644
--- a/cryptography/hazmat/backends/multibackend.py
+++ b/cryptography/hazmat/backends/multibackend.py
@@ -16,7 +16,7 @@
 from cryptography import utils
 from cryptography.exceptions import UnsupportedAlgorithm
 from cryptography.hazmat.backends.interfaces import (
-    CipherBackend, HashBackend, HMACBackend, PBKDF2HMACBackend
+    CipherBackend, HashBackend, HMACBackend, PBKDF2HMACBackend, RSABackend
 )
 
 
@@ -101,3 +101,8 @@
             except UnsupportedAlgorithm:
                 pass
         raise UnsupportedAlgorithm
+
+    def generate_rsa_private_key(self, public_exponent, key_size):
+        for b in self._filtered_backends(RSABackend):
+            return b.generate_rsa_private_key(public_exponent, key_size)
+        raise UnsupportedAlgorithm
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index d886932..fc3c3bd 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -22,15 +22,15 @@
 from cryptography.hazmat.backends.interfaces import (
     CipherBackend, HashBackend, HMACBackend, PBKDF2HMACBackend, RSABackend
 )
+from cryptography.hazmat.bindings.openssl.binding import Binding
 from cryptography.hazmat.primitives import interfaces, hashes
+from cryptography.hazmat.primitives.asymmetric import rsa
 from cryptography.hazmat.primitives.ciphers.algorithms import (
     AES, Blowfish, Camellia, TripleDES, ARC4,
 )
 from cryptography.hazmat.primitives.ciphers.modes import (
     CBC, CTR, ECB, OFB, CFB, GCM,
 )
-from cryptography.hazmat.bindings.openssl.binding import Binding
-from cryptography.hazmat.primitives.asymmetric import rsa
 
 
 @utils.register_interface(CipherBackend)
diff --git a/cryptography/hazmat/primitives/asymmetric/rsa.py b/cryptography/hazmat/primitives/asymmetric/rsa.py
index 1b33eaa..60c5c80 100644
--- a/cryptography/hazmat/primitives/asymmetric/rsa.py
+++ b/cryptography/hazmat/primitives/asymmetric/rsa.py
@@ -109,6 +109,10 @@
         self._public_exponent = public_exponent
         self._modulus = modulus
 
+    @classmethod
+    def generate(self, public_exponent, key_size, backend):
+        return backend.generate_rsa_private_key(public_exponent, key_size)
+
     @property
     def key_size(self):
         return _bit_length(self.modulus)
diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst
index e388087..d6351c9 100644
--- a/docs/hazmat/backends/openssl.rst
+++ b/docs/hazmat/backends/openssl.rst
@@ -62,7 +62,9 @@
 On OS X and FreeBSD ``/dev/urandom`` is an alias for ``/dev/random`` and
 utilizes the `Yarrow`_ algorithm.
 
-On Windows ``CryptGenRandom`` is backed by `Fortuna`_.
+On Windows the implementation of ``CryptGenRandom`` depends on which version of
+the operation system you are using. See the `Microsoft documentation`_ for more
+details.
 
 Linux uses its own PRNG design. ``/dev/urandom`` is a non-blocking source seeded
 from the same pool as ``/dev/random``.
@@ -71,4 +73,4 @@
 .. _`OpenSSL`: https://www.openssl.org/
 .. _`initializing the RNG`: http://en.wikipedia.org/wiki/OpenSSL#Vulnerability_in_the_Debian_implementation
 .. _`Yarrow`: http://en.wikipedia.org/wiki/Yarrow_algorithm
-.. _`Fortuna`: http://en.wikipedia.org/wiki/Fortuna_(PRNG)
+.. _`Microsoft documentation`: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx
diff --git a/docs/hazmat/primitives/padding.rst b/docs/hazmat/primitives/padding.rst
index da5a95d..83154c0 100644
--- a/docs/hazmat/primitives/padding.rst
+++ b/docs/hazmat/primitives/padding.rst
@@ -23,16 +23,18 @@
 
         >>> from cryptography.hazmat.primitives import padding
         >>> padder = padding.PKCS7(128).padder()
-        >>> padder.update(b"1111111111")
-        ''
-        >>> padded_data = padder.finalize()
+        >>> padded_data = padder.update(b"11111111111111112222222222")
         >>> padded_data
-        '1111111111\x06\x06\x06\x06\x06\x06'
+        '1111111111111111'
+        >>> padded_data += padder.finalize()
+        >>> padded_data
+        '11111111111111112222222222\x06\x06\x06\x06\x06\x06'
         >>> unpadder = padding.PKCS7(128).unpadder()
-        >>> unpadder.update(padded_data)
-        ''
-        >>> unpadder.finalize()
-        '1111111111'
+        >>> data = unpadder.update(padded_data)
+        >>> data
+        '1111111111111111'
+        >>> data + unpadder.finalize()
+        '11111111111111112222222222'
 
     :param block_size: The size of the block in bits that the data is being
                        padded to.
diff --git a/docs/hazmat/primitives/rsa.rst b/docs/hazmat/primitives/rsa.rst
index 7c6356c..a19ada3 100644
--- a/docs/hazmat/primitives/rsa.rst
+++ b/docs/hazmat/primitives/rsa.rst
@@ -13,9 +13,10 @@
 
     An RSA private key is required for decryption and signing of messages.
 
-    Normally you do not need to directly construct private keys because you'll
-    be loading them from a file or generating them automatically.
-
+    You should use
+    :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.generate`
+    to generate new keys.
+    
     .. warning::
         This method only checks a limited set of properties of its arguments.
         Using an RSA that you do not trust or with incorrect parameters may
@@ -23,6 +24,7 @@
         recommend that you only ever load private keys that were generated with
         software you trust.
 
+
     This class conforms to the
     :class:`~cryptography.hazmat.primitives.interfaces.RSAPrivateKey`
     interface.
@@ -33,6 +35,22 @@
                         `private_exponent`, `public_exponent` or `modulus` do 
                         not match the bounds specified in `RFC 3447`_.
 
+    .. classmethod:: generate(public_exponent, key_size, backend)
+
+        Generate a new ``RSAPrivateKey`` instance using ``backend``.
+
+        :param int public_exponent: The public exponent of the new key.
+            Usually one of the small Fermat primes 3, 5, 17, 257, 65537. If in
+            doubt you should `use 65537`_.
+        :param int key_size: The length of the modulus in bits. For keys
+            generated in 2014 this should be `at least 2048`_. (See page 41.)
+            Must be at least 512. Some backends may have additional
+            limitations.
+        :param backend: A
+            :class:`~cryptography.hazmat.backends.interfaces.RSABackend`
+            provider.
+        :return: A new instance of ``RSAPrivateKey``.
+
 .. class:: RSAPublicKey(public_exponent, modulus)
     
     .. versionadded:: 0.2
@@ -56,3 +74,5 @@
 .. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
 .. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
 .. _`RFC 3447`: https://tools.ietf.org/html/rfc3447
+.. _`use 65537`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
+.. _`at least 2048`: http://www.ecrypt.eu.org/documents/D.SPA.20.pdf
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index ca21c9f..ce77ce2 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -16,7 +16,7 @@
 from cryptography import utils
 from cryptography.exceptions import UnsupportedAlgorithm
 from cryptography.hazmat.backends.interfaces import (
-    CipherBackend, HashBackend, HMACBackend, PBKDF2HMACBackend
+    CipherBackend, HashBackend, HMACBackend, PBKDF2HMACBackend, RSABackend
 )
 from cryptography.hazmat.backends.multibackend import MultiBackend
 from cryptography.hazmat.primitives import hashes, hmac
@@ -67,7 +67,7 @@
 
 
 @utils.register_interface(PBKDF2HMACBackend)
-class DummyPBKDF2HMAC(object):
+class DummyPBKDF2HMACBackend(object):
     def __init__(self, supported_algorithms):
         self._algorithms = supported_algorithms
 
@@ -80,6 +80,12 @@
             raise UnsupportedAlgorithm
 
 
+@utils.register_interface(RSABackend)
+class DummyRSABackend(object):
+    def generate_rsa_private_key(self, public_exponent, private_key):
+        pass
+
+
 class TestMultiBackend(object):
     def test_ciphers(self):
         backend = MultiBackend([
@@ -134,7 +140,7 @@
 
     def test_pbkdf2(self):
         backend = MultiBackend([
-            DummyPBKDF2HMAC([hashes.MD5])
+            DummyPBKDF2HMACBackend([hashes.MD5])
         ])
         assert backend.pbkdf2_hmac_supported(hashes.MD5())
 
@@ -142,3 +148,16 @@
 
         with pytest.raises(UnsupportedAlgorithm):
             backend.derive_pbkdf2_hmac(hashes.SHA1(), 10, b"", 10, b"")
+
+    def test_rsa(self):
+        backend = MultiBackend([
+            DummyRSABackend()
+        ])
+
+        backend.generate_rsa_private_key(
+            key_size=1024, public_exponent=65537
+        )
+
+        backend = MultiBackend([])
+        with pytest.raises(UnsupportedAlgorithm):
+            backend.generate_rsa_private_key(key_size=1024, public_exponent=3)
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
index fdd55e7..0e930e4 100644
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -49,26 +49,32 @@
         )
     )
     def test_generate_rsa_keys(self, backend, public_exponent, key_size):
-        skey = backend.generate_rsa_private_key(public_exponent, key_size)
+        skey = rsa.RSAPrivateKey.generate(public_exponent, key_size, backend)
         _check_rsa_private_key(skey)
         assert skey.key_size == key_size
         assert skey.public_exponent == public_exponent
 
     def test_generate_bad_rsa_key(self, backend):
         with pytest.raises(ValueError):
-            backend.generate_rsa_private_key(public_exponent=1, key_size=2048)
+            rsa.RSAPrivateKey.generate(public_exponent=1,
+                                       key_size=2048,
+                                       backend=backend)
 
         with pytest.raises(ValueError):
-            backend.generate_rsa_private_key(public_exponent=4, key_size=2048)
+            rsa.RSAPrivateKey.generate(public_exponent=4,
+                                       key_size=2048,
+                                       backend=backend)
 
     def test_cant_generate_insecure_tiny_key(self, backend):
         with pytest.raises(ValueError):
-            backend.generate_rsa_private_key(public_exponent=65537,
-                                             key_size=511)
+            rsa.RSAPrivateKey.generate(public_exponent=65537,
+                                       key_size=511,
+                                       backend=backend)
 
         with pytest.raises(ValueError):
-            backend.generate_rsa_private_key(public_exponent=65537,
-                                             key_size=256)
+            rsa.RSAPrivateKey.generate(public_exponent=65537,
+                                       key_size=256,
+                                       backend=backend)
 
     @pytest.mark.parametrize(
         "pkcs1_example",