Пример #1
0
 def test_readwithlen(self):
     s="A quick brown fox jumps over a lazy dog"
     bio=Membio(s)
     data=bio.read(len(s))
     self.assertEqual(data,s)
     data2=bio.read(5)
     self.assertEqual(data2,"")
Пример #2
0
 def test_readwithlen(self):
     s = b"A quick brown fox jumps over a lazy dog"
     bio = Membio(s)
     data = bio.read(len(s))
     self.assertEqual(data, s)
     data2 = bio.read(5)
     self.assertEqual(data2, b"")
Пример #3
0
 def __unicode__(self):
     """
     Produces unicode representation of the name.
     """
     bio = Membio()
     libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0, self.PRINT_FLAG)
     return bio.__unicode__()
Пример #4
0
 def __init__(self, ptr=None, privkey=None, pubkey=None, format="PEM",
              cansign=False, password=None, callback=_cb):
     if not ptr is None:
         self.key = ptr
         self.cansign = cansign
         if not privkey is None or not pubkey is None:
             raise TypeError("Just one of ptr, pubkey or privkey can " +
                             "be specified")
     elif not privkey is None:
         if not pubkey is None:
             raise TypeError("Just one of ptr, pubkey or privkey can " +
                             "be specified")
         bio = Membio(privkey)
         self.cansign = True
         if format == "PEM":
             self.key = libcrypto.PEM_read_bio_PrivateKey(bio.bio, None,
                                                          callback,
                                                          c_char_p(password))
         else:
             self.key = libcrypto.d2i_PrivateKey_bio(bio.bio, None)
         if self.key is None:
             raise PKeyError("error parsing private key")
     elif not pubkey is None:
         bio = Membio(pubkey)
         self.cansign = False
         if format == "PEM":
             self.key = libcrypto.PEM_read_bio_PUBKEY(bio.bio, None,
                                                      callback,
                                                      c_char_p(password))
         else:
             self.key = libcrypto.d2i_PUBKEY_bio(bio.bio, None)
         if self.key is None:
             raise PKeyError("error parsing public key")
     else:
         raise TypeError("Neither public, nor private key is specified")
Пример #5
0
 def test_unicode(self):
     b = Membio()
     s = b'\xd0\xba\xd0\xb0\xd0\xba \xd1\x8d\xd1\x82\xd0\xbe \xd0\xbf\xd0\xbe-\xd1\x80\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8'
     b.write(s)
     self.assertEqual(
         unicode(b),
         u'\u043a\u0430\u043a \u044d\u0442\u043e \u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438'
     )
Пример #6
0
 def test_readshortstr(self):
     s = b"A quick brown fox jumps over a lazy dog"
     bio = Membio(s)
     data = bio.read()
     self.assertEqual(data, s)
     data2 = bio.read()
     self.assertEqual(data2, b"")
     del bio
Пример #7
0
 def test_readshortstr(self):
     s="A quick brown fox jumps over a lazy dog"
     bio=Membio(s)
     data=bio.read()
     self.assertEqual(data,s)
     data2=bio.read()
     self.assertEqual(data2,"")
     del bio
Пример #8
0
def _keybio(blob, format):
    # But DER string should be binary
    if format == "PEM" and isinstance(blob, chartype):
        return Membio(blob.encode("ascii"), clone=True)
    elif isinstance(blob, bintype):
        return Membio(blob)
    else:
        raise TypeError("Key should be either blob or PEM string")
Пример #9
0
 def test_reset(self):
     s="A quick brown fox jumps over a lazy dog"
     bio=Membio(s)
     data=bio.read()
     bio.reset()
     data2=bio.read()
     del bio
     self.assertEqual(data,data2)
     self.assertEqual(data,s)
Пример #10
0
 def __bytes__(self):
     """
     Produces an ascii representation of the name, escaping all
     symbols > 0x80.  Probably it is not what you want, unless
     your native language is English
     """
     bio = Membio()
     libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0,
                                  self.PRINT_FLAG | self.ESC_MSB)
     return bio.__bytes__()
Пример #11
0
    def test_readlongstr(self):
        poem = b'''Eyes of grey--a sodden quay,
Driving rain and falling tears,
As the steamer wears to sea
In a parting storm of cheers.

Sing, for Faith and Hope are high--
None so true as you and I--
Sing the Lovers' Litany:
"Love like ours can never die!"

Eyes of black--a throbbing keel,
Milky foam to left and right;
Whispered converse near the wheel
In the brilliant tropic night.

Cross that rules the Southern Sky!
Stars that sweep and wheel and fly,
Hear the Lovers' Litany:
Love like ours can never die!"

Eyes of brown--a dusty plain
Split and parched with heat of June,
Flying hoof and tightened rein,
Hearts that beat the old, old tune.

Side by side the horses fly,
Frame we now the old reply
Of the Lovers' Litany:
"Love like ours can never die!"

Eyes of blue--the Simla Hills
Silvered with the moonlight hoar;
Pleading of the waltz that thrills,
Dies and echoes round Benmore.

"Mabel," "Officers," "Goodbye,"
Glamour, wine, and witchery--
On my soul's sincerity,
"Love like ours can never die!"

Maidens of your charity,
Pity my most luckless state.
Four times Cupid's debtor I--
Bankrupt in quadruplicate.

Yet, despite this evil case,
And a maiden showed me grace,
Four-and-forty times would I
Sing the Lovers' Litany:
"Love like ours can never die!"'''
        bio = Membio(poem)
        data = bio.read()
        self.assertEqual(data, poem)
        del bio
Пример #12
0
    def test_readlongstr(self):
        poem='''Eyes of grey--a sodden quay,
Driving rain and falling tears,
As the steamer wears to sea
In a parting storm of cheers.

Sing, for Faith and Hope are high--
None so true as you and I--
Sing the Lovers' Litany:
"Love like ours can never die!"

Eyes of black--a throbbing keel,
Milky foam to left and right;
Whispered converse near the wheel
In the brilliant tropic night.

Cross that rules the Southern Sky!
Stars that sweep and wheel and fly,
Hear the Lovers' Litany:
Love like ours can never die!"

Eyes of brown--a dusty plain
Split and parched with heat of June,
Flying hoof and tightened rein,
Hearts that beat the old, old tune.

Side by side the horses fly,
Frame we now the old reply
Of the Lovers' Litany:
"Love like ours can never die!"

Eyes of blue--the Simla Hills
Silvered with the moonlight hoar;
Pleading of the waltz that thrills,
Dies and echoes round Benmore.

"Mabel," "Officers," "Goodbye,"
Glamour, wine, and witchery--
On my soul's sincerity,
"Love like ours can never die!"

Maidens of your charity,
Pity my most luckless state.
Four times Cupid's debtor I--
Bankrupt in quadruplicate.

Yet, despite this evil case,
And a maiden showed me grace,
Four-and-forty times would I
Sing the Lovers' Litany:
"Love like ours can never die!"'''
        bio=Membio(poem)
        data=bio.read()
        self.assertEqual(data,poem)
        del bio
Пример #13
0
 def test_readparts(self):
     s="A quick brown fox jumps over the lazy dog"
     bio=Membio(s)
     a=bio.read(10)
     self.assertEqual(a,s[0:10])
     b=bio.read(9)
     self.assertEqual(b,s[10:19])
     c=bio.read()
     self.assertEqual(c,s[19:])
     d=bio.read()
     self.assertEqual(d,"")
Пример #14
0
 def exportpriv(self, format="PEM", password=None, cipher=None,
                callback=_cb):
     """
     Returns private key as PEM or DER Structure.
     If password and cipher are specified, encrypts key
     on given password, using given algorithm. Cipher must be
     an ctypescrypto.cipher.CipherType object
     """
     bio = Membio()
     if cipher is None:
         evp_cipher = None
     else:
         evp_cipher = cipher.cipher
     if format == "PEM":
         ret = libcrypto.PEM_write_bio_PrivateKey(bio.bio, self.key,
                                                  evp_cipher, None, 0,
                                                  callback,
                                                  c_char_p(password))
     else:
         ret = libcrypto.i2d_PKCS8PrivateKey_bio(bio.bio, self.key,
                                                 evp_cipher, None, 0,
                                                 callback,
                                                 c_char_p(password))
     if ret == 0:
         raise PKeyError("error serializing private key")
     return str(bio)
Пример #15
0
def CMS(data, format="PEM"):
    """
    Factory function to create CMS objects from received messages.
    
    Parses CMS data and returns either SignedData or EnvelopedData
    object. format argument can be either "PEM" or "DER".

    It determines object type from the contents of received CMS
    structure.
    """
    bio = Membio(data)
    if format == "PEM":
        ptr = libcrypto.PEM_read_bio_CMS(bio.bio, None, None, None)
    else:
        ptr = libcrypto.d2i_CMS_bio(bio.bio, None)
    if ptr is None:
        raise CMSError("Error parsing CMS data")
    typeoid = Oid(libcrypto.OBJ_obj2nid(libcrypto.CMS_get0_type(ptr)))
    if typeoid.shortname() == "pkcs7-signedData":
        return SignedData(ptr)
    elif typeoid.shortname() == "pkcs7-envelopedData":
        return EnvelopedData(ptr)
    elif typeoid.shortname() == "pkcs7-encryptedData":
        return EncryptedData(ptr)
    else:
        raise NotImplementedError("cannot handle " + typeoid.shortname())
Пример #16
0
    def create(data, cert, pkey, flags=Flags.BINARY, certs=None):
        """
            Creates SignedData message by signing data with pkey and
            certificate.

            @param data - data to sign
            @param cert - signer's certificate
            @param pkey - pkey object with private key to sign
            @param flags - OReed combination of Flags constants
            @param certs - list of X509 objects to include into CMS
        """
        if not pkey.cansign:
            raise ValueError("Specified keypair has no private part")
        if cert.pubkey != pkey:
            raise ValueError("Certificate doesn't match public key")
        bio = Membio(data)
        if certs is not None and len(certs) > 0:
            certstack = StackOfX509(certs).ptr
        else:
            certstack = None
        ptr = libcrypto.CMS_sign(cert.cert, pkey.key, certstack, bio.bio,
                                 flags)
        if ptr is None:
            raise CMSError("signing message")
        return SignedData(ptr)
Пример #17
0
 def sign(self,
          cert,
          pkey,
          digest_type=None,
          data=None,
          flags=Flags.BINARY):
     """
         Adds another signer to already signed message
         @param cert - signer's certificate
         @param pkey - signer's private key
         @param digest_type - message digest to use as DigestType object
             (if None - default for key would be used)
         @param data - data to sign (if detached and
                 Flags.REUSE_DIGEST is not specified)
         @param flags - ORed combination of Flags consants
     """
     if not pkey.cansign:
         raise ValueError("Specified keypair has no private part")
     if cert.pubkey != pkey:
         raise ValueError("Certificate doesn't match public key")
     if libcrypto.CMS_add1_signer(self.ptr, cert.cert, pkey.key,
                                  digest_type.digest, flags) is None:
         raise CMSError("adding signer")
     if flags & Flags.REUSE_DIGEST == 0:
         if data is not None:
             bio = Membio(data)
             biodata = bio.bio
         else:
             biodata = None
         res = libcrypto.CMS_final(self.ptr, biodata, None, flags)
         if res <= 0:
             raise CMSError("Cannot finalize CMS")
Пример #18
0
    def verify(self, store, flags, data=None, certs=None):
        """
        Verifies signature under CMS message using trusted cert store

        @param store -  X509Store object with trusted certs
        @param flags - OR-ed combination of flag consants
        @param data - message data, if messge has detached signature
        param certs - list of certificates to use during verification
                If Flags.NOINTERN is specified, these are only
                sertificates to search for signing certificates
        @returns True if signature valid, False otherwise
        """
        bio = None
        if data != None:
            bio_obj = Membio(data)
            bio = bio_obj.bio
        if certs is not None and len(certs) > 0:
            certstack_obj = StackOfX509(
                certs)  # keep reference to prevent immediate __del__ call
            certstack = certstack_obj.ptr
        else:
            certstack = None
        res = libcrypto.CMS_verify(self.ptr, certstack, store.store, bio, None,
                                   flags)
        return res > 0
Пример #19
0
    def exportpriv(self, format="PEM", password=None, cipher=None):
        """
        Returns private key as PEM or DER Structure.
        If password and cipher are specified, encrypts key
        on given password, using given algorithm. Cipher must be
        an ctypescrypto.cipher.CipherType object

        Password can be either string or function with one argument,
        which returns password. It is called with argument True, which
        means, that we are encrypting key, and password should be
        verified (requested twice from user, for example).
        """
        bio = Membio()
        if cipher is None:
            evp_cipher = None
        else:
            evp_cipher = cipher.cipher
        if format == "PEM":
            ret = libcrypto.PEM_write_bio_PrivateKey(
                bio.bio, self.key, evp_cipher, None, 0,
                _password_callback(password), None)
            if ret == 0:
                raise PKeyError("error serializing private key")
            return str(bio)
        else:
            ret = libcrypto.i2d_PKCS8PrivateKey_bio(
                bio.bio, self.key, evp_cipher, None, 0,
                _password_callback(password), None)
            if ret == 0:
                raise PKeyError("error serializing private key")
            return bintype(bio)
Пример #20
0
 def pem(self):
     """
     Serialize in PEM format
     """
     bio = Membio()
     if not libcrypto.PEM_write_bio_CMS(bio.bio, self.ptr):
         raise CMSError("writing CMS to PEM")
     return str(bio)
Пример #21
0
 def __str__(self):
     """
     Serialize in DER format
     """
     bio = Membio()
     if not libcrypto.i2d_CMS_bio(bio.bio, self.ptr):
         raise CMSError("writing CMS to DER")
     return str(bio)
Пример #22
0
def _X509__asn1date_to_datetime(asn1date):
    """ 
    Converts openssl ASN1_TIME object to python datetime.datetime
    """
    bio = Membio()
    libcrypto.ASN1_TIME_print(bio.bio, asn1date)
    pydate = datetime.strptime(str(bio), "%b %d %H:%M:%S %Y %Z")
    return pydate.replace(tzinfo=utc)
Пример #23
0
 def data(self):
     """
     Returns signed data if present in the message
     """
     bio = Membio()
     if not libcrypto.CMS_verify(self.ptr, None, None, None, bio.bio,
                                 Flags.NO_VERIFY):
         raise CMSError("extract data")
     return str(bio)
Пример #24
0
 def decrypt(self, key, flags=0):
     """
     Decrypts encrypted data message
     @param key - symmetic key to decrypt
     @param flags - OR-ed combination of Flags constant
     """
     bio = Membio()
     if libcrypto.CMS_EncryptedData_decrypt(self.ptr, key, len(key), None,
                                            bio.bio, flags) <= 0:
         raise CMSError("decrypt data")
     return str(bio)
Пример #25
0
 def exportpub(self, format="PEM"):
     """
     Returns public key as PEM or DER structure.
     """
     bio = Membio()
     if format == "PEM":
         retcode = libcrypto.PEM_write_bio_PUBKEY(bio.bio, self.key)
     else:
         retcode = libcrypto.i2d_PUBKEY_bio(bio.bio, self.key)
     if retcode == 0:
         raise PKeyError("error serializing public key")
     return str(bio)
Пример #26
0
 def __getitem__(self, key):
     if isinstance(key, Oid):
         # Return first matching field
         idx = libcrypto.X509_NAME_get_index_by_NID(self.ptr, key.nid, -1)
         if idx < 0:
             raise KeyError("Key not found " + str(Oid))
         entry = libcrypto.X509_NAME_get_entry(self.ptr, idx)
         value = libcrypto.X509_NAME_ENTRY_get_data(entry)
         bio = Membio()
         libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
         return chartype(bio)
     elif isinstance(key, inttype):
         # Return OID, string tuple
         entry = libcrypto.X509_NAME_get_entry(self.ptr, key)
         if entry is None:
             raise IndexError("name entry index out of range")
         oid = Oid.fromobj(libcrypto.X509_NAME_ENTRY_get_object(entry))
         value = libcrypto.X509_NAME_ENTRY_get_data(entry)
         bio = Membio()
         libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
         return (oid, chartype(bio))
     else:
         raise TypeError("X509 NAME can be indexed by Oids or integers only")
Пример #27
0
 def test_reset(self):
     s = b"A quick brown fox jumps over a lazy dog"
     bio = Membio(s)
     data = bio.read()
     bio.reset()
     data2 = bio.read()
     del bio
     self.assertEqual(data, data2)
     self.assertEqual(data, s)
Пример #28
0
 def create(data, cipher, key, flags=0):
     """
     Creates an EncryptedData message.
     @param data data to encrypt
     @param cipher cipher.CipherType object represening required
             cipher type
     @param key - byte array used as simmetic key
     @param flags - OR-ed combination of Flags constant
     """
     bio = Membio(data)
     ptr = libcrypto.CMS_EncryptedData_encrypt(bio.bio, cipher.cipher, key,
                                               len(key), flags)
     if ptr is None:
         raise CMSError("encrypt data")
     return EncryptedData(ptr)
Пример #29
0
 def create(recipients, data, cipher, flags=0):
     """
     Creates and encrypts message
     @param recipients - list of X509 objects
     @param data - contents of the message
     @param cipher - CipherType object
     @param flags - flag
     """
     recp = StackOfX509(recipients)
     bio = Membio(data)
     cms_ptr = libcrypto.CMS_encrypt(recp.ptr, bio.bio, cipher.cipher,
                                     flags)
     if cms_ptr is None:
         raise CMSError("encrypt EnvelopedData")
     return EnvelopedData(cms_ptr)
Пример #30
0
 def test_readparts(self):
     s = b"A quick brown fox jumps over the lazy dog"
     bio = Membio(s)
     a = bio.read(10)
     self.assertEqual(a, s[0:10])
     b = bio.read(9)
     self.assertEqual(b, s[10:19])
     c = bio.read()
     self.assertEqual(c, s[19:])
     d = bio.read()
     self.assertEqual(d, b"")
Пример #31
0
 def decrypt(self, pkey, cert, flags=0):
     """
     Decrypts message
     @param pkey - private key to decrypt
     @param cert - certificate of this private key (to find
         neccessary RecipientInfo
     @param flags - flags
     @returns - decrypted data
     """
     if not pkey.cansign:
         raise ValueError("Specified keypair has no private part")
     if pkey != cert.pubkey:
         raise ValueError("Certificate doesn't match private key")
     bio = Membio()
     res = libcrypto.CMS_decrypt(self.ptr, pkey.key, cert.cert, None,
                                 bio.bio, flags)
     if res <= 0:
         raise CMSError("decrypting CMS")
     return str(bio)
Пример #32
0
def CMS(data, format="PEM"):
    """
    Parses CMS data and returns either SignedData or EnvelopedData
    object
    """
    bio = Membio(data)
    if format == "PEM":
        ptr = libcrypto.PEM_read_bio_CMS(bio.bio, None, None, None)
    else:
        ptr = libcrypto.d2i_CMS_bio(bio.bio, None)
    if ptr is None:
        raise CMSError("Error parsing CMS data")
    typeoid = Oid(libcrypto.OBJ_obj2nid(libcrypto.CMS_get0_type(ptr)))
    if typeoid.shortname() == "pkcs7-signedData":
        return SignedData(ptr)
    elif typeoid.shortname() == "pkcs7-envelopedData":
        return EnvelopedData(ptr)
    elif typeoid.shortname() == "pkcs7-encryptedData":
        return EncryptedData(ptr)
    else:
        raise NotImplementedError("cannot handle " + typeoid.shortname())
Пример #33
0
 def __init__(self, data=None, ptr=None, format="PEM"):
     """
     Initializes certificate
     @param data - serialized certificate in PEM or DER format.
     @param ptr - pointer to X509, returned by some openssl function.
         mutually exclusive with data
     @param format - specifies data format. "PEM" or "DER", default PEM
     """
     if ptr is not None:
         if data is not None:
             raise TypeError("Cannot use data and ptr simultaneously")
         self.cert = ptr
     elif data is None:
         raise TypeError("data argument is required")
     else:
         bio = Membio(data)
         if format == "PEM":
             self.cert = libcrypto.PEM_read_bio_X509(bio.bio, None, None,
                                                     None)
         else:
             self.cert = libcrypto.d2i_X509_bio(bio.bio, None)
         if self.cert is None:
             raise X509Error("error reading certificate")
     self.extensions = _X509extlist(self)
Пример #34
0
 def serial(self):
     """ Serial number of certificate as integer """
     asnint = libcrypto.X509_get_serialNumber(self.cert)
     bio = Membio()
     libcrypto.i2a_ASN1_INTEGER(bio.bio, asnint)
     return int(str(bio), 16)
Пример #35
0
 def pem(self):
     """ Returns PEM represntation of the certificate """
     bio = Membio()
     if libcrypto.PEM_write_bio_X509(bio.bio, self.cert) == 0:
         raise X509Error("error serializing certificate")
     return str(bio)
Пример #36
0
 def test_write(self):
     b=Membio()
     b.write("A quick brown ")
     b.write("fox jumps over ")
     b.write("the lazy dog.")
     self.assertEqual(str(b),"A quick brown fox jumps over the lazy dog.")
Пример #37
0
 def test_readwrongtype(self):
     s="A quick brown fox jumps over a lazy dog"
     bio=Membio(s)
     with self.assertRaises(TypeError):
         data=bio.read("5")
Пример #38
0
 def test_unicode(self):
     b=Membio()
     s='\xd0\xba\xd0\xb0\xd0\xba \xd1\x8d\xd1\x82\xd0\xbe \xd0\xbf\xd0\xbe-\xd1\x80\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8'
     b.write(s)
     self.assertEqual(unicode(b),u'\u043a\u0430\u043a \u044d\u0442\u043e \u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438')
Пример #39
0
 def test_unicode2(self):
     b=Membio()
     u=u'\u043a\u0430\u043a \u044d\u0442\u043e \u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438'
     b.write(u)
     self.assertEqual(unicode(b),u)