Beispiel #1
0
 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'))
Beispiel #2
0
 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'))
Beispiel #3
0
    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()
Beispiel #4
0
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()
Beispiel #5
0
 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'))
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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
Beispiel #9
0
 def testDecode2(self):
     # Verify that decode returns the object
     der = DerBitString()
     self.assertEquals(der, der.decode(b('\x03\x00')))
Beispiel #10
0
 def testInit2(self):
     der = DerBitString(DerInteger(1))
     self.assertEquals(der.encode(), b('\x03\x04\x00\x02\x01\x01'))
Beispiel #11
0
 def testInit1(self):
     der = DerBitString(b("\xFF"))
     self.assertEquals(der.encode(), b('\x03\x02\x00\xFF'))
Beispiel #12
0
 def testDecode2(self):
     # Verify that decode returns the object
     der = DerBitString()
     self.assertEquals(der, der.decode(b('\x03\x00')))
Beispiel #13
0
 def testInit2(self):
     der = DerBitString(DerInteger(1))
     self.assertEquals(der.encode(), b('\x03\x04\x00\x02\x01\x01'))
Beispiel #14
0
 def testInit1(self):
     der = DerBitString(b("\xFF"))
     self.assertEquals(der.encode(), b('\x03\x02\x00\xFF'))