def testDecode1(self): # Empty sequence der = DerBitString() der.decode(b('\x03\x00')) self.assertEquals(der.value, b('')) # Small payload der.decode(b('\x03\x03\x00\x01\x02')) self.assertEquals(der.value, b('\x01\x02'))
def testEncode1(self): # Empty sequence der = DerBitString() self.assertEquals(der.encode(), b('\x03\x01\x00')) # Small payload der = DerBitString(b('\x01\x02')) self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02')) # Small payload der = DerBitString() der.value = b('\x01\x02') self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02'))
def _export_private_der(self, include_ec_params=True): assert self.has_private() # ECPrivateKey ::= SEQUENCE { # version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # privateKey OCTET STRING, # parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, # publicKey [1] BIT STRING OPTIONAL # } # Public key - uncompressed form order_bytes = _curve.order.size_in_bytes() public_key = (b'\x04' + self.pointQ.x.to_bytes(order_bytes) + self.pointQ.y.to_bytes(order_bytes)) seq = [ 1, DerOctetString(self.d.to_bytes(order_bytes)), DerObjectId(_curve.oid, explicit=0), DerBitString(public_key, explicit=1) ] if not include_ec_params: del seq[2] return DerSequence(seq).encode()
def _create_subject_public_key_info(algo_oid, secret_key, params=None): if params is None: params = DerNull() spki = DerSequence([ DerSequence([DerObjectId(algo_oid), params]), DerBitString(secret_key) ]) return spki.encode()
def testDecode1(self): # Empty sequence der = DerBitString() der.decode(b('\x03\x00')) self.assertEqual(der.value, b('')) # Small payload der.decode(b('\x03\x03\x00\x01\x02')) self.assertEqual(der.value, b('\x01\x02'))
def _import_private_der(encoded, passphrase, curve_oid=None): # See RFC5915 https://tools.ietf.org/html/rfc5915 # # ECPrivateKey ::= SEQUENCE { # version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # privateKey OCTET STRING, # parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, # publicKey [1] BIT STRING OPTIONAL # } private_key = DerSequence().decode(encoded, nr_elements=(3, 4)) if private_key[0] != 1: raise ValueError("Incorrect ECC private key version") try: parameters = DerObjectId(explicit=0).decode(private_key[2]).value if curve_oid is not None and parameters != curve_oid: raise ValueError("Curve mismatch") curve_oid = parameters except ValueError: pass if curve_oid is None: raise ValueError("No curve found") for curve_name, curve in _curves.items(): if curve.oid == curve_oid: break else: raise UnsupportedEccFeature("Unsupported ECC curve (OID: %s)" % curve_oid) scalar_bytes = DerOctetString().decode(private_key[1]).payload modulus_bytes = curve.p.size_in_bytes() if len(scalar_bytes) != modulus_bytes: raise ValueError("Private key is too small") d = Integer.from_bytes(scalar_bytes) # Decode public key (if any) if len(private_key) == 4: public_key_enc = DerBitString(explicit=1).decode(private_key[3]).value public_key = _import_public_der(public_key_enc, curve_oid=curve_oid) point_x = public_key.pointQ.x point_y = public_key.pointQ.y else: point_x = point_y = None return construct(curve=curve_name, d=d, point_x=point_x, point_y=point_y)
def _import_private_der(encoded, passphrase, curve_name=None): # ECPrivateKey ::= SEQUENCE { # version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # privateKey OCTET STRING, # parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, # publicKey [1] BIT STRING OPTIONAL # } private_key = DerSequence().decode(encoded, nr_elements=(3, 4)) if private_key[0] != 1: raise ValueError("Incorrect ECC private key version") try: curve_name = DerObjectId(explicit=0).decode(private_key[2]).value except ValueError: pass if curve_name != _curve.oid: raise UnsupportedEccFeature("Unsupported ECC curve (OID: %s)" % curve_name) scalar_bytes = DerOctetString().decode(private_key[1]).payload order_bytes = _curve.order.size_in_bytes() if len(scalar_bytes) != order_bytes: raise ValueError("Private key is too small") d = Integer.from_bytes(scalar_bytes) # Decode public key (if any, it must be P-256) if len(private_key) == 4: public_key_enc = DerBitString(explicit=1).decode(private_key[3]).value public_key = _import_public_der(curve_name, public_key_enc) point_x = public_key.pointQ.x point_y = public_key.pointQ.y else: point_x = point_y = None return construct(curve="P-256", d=d, point_x=point_x, point_y=point_y)
def _expand_subject_public_key_info(encoded): """Parse a SubjectPublicKeyInfo structure. It returns a triple with: * OID (string) * encoded public key (bytes) * Algorithm parameters (bytes or None) """ # # SubjectPublicKeyInfo ::= SEQUENCE { # algorithm AlgorithmIdentifier, # subjectPublicKey BIT STRING # } # # AlgorithmIdentifier ::= SEQUENCE { # algorithm OBJECT IDENTIFIER, # parameters ANY DEFINED BY algorithm OPTIONAL # } # spki = DerSequence().decode(encoded, nr_elements=2) algo = DerSequence().decode(spki[0], nr_elements=(1, 2)) algo_oid = DerObjectId().decode(algo[0]) spk = DerBitString().decode(spki[1]).value if len(algo) == 1: algo_params = None else: try: DerNull().decode(algo[1]) algo_params = None except: algo_params = algo[1] return algo_oid.value, spk, algo_params
def testDecode2(self): # Verify that decode returns the object der = DerBitString() self.assertEquals(der, der.decode(b('\x03\x00')))
def testInit2(self): der = DerBitString(DerInteger(1)) self.assertEquals(der.encode(), b('\x03\x04\x00\x02\x01\x01'))
def testInit1(self): der = DerBitString(b("\xFF")) self.assertEquals(der.encode(), b('\x03\x02\x00\xFF'))