#!/usr/bin/env python
"""
Somewhere, the HSM has to have a last-gasp default PIN, even if it's
only the null string, because there has to be **some** way to
initialize the poor thing. Absent a better plan (feel free to
suggest one!), this last-gasp default is compiled in.
The normal value of this last-gasp PIN is deliberately chosen to be
annoying, so that people will change it, but since the derevation
requires running PBKDF2 and you might want a different default if
you're compiling this for yourself, we provide the script that
generates the default.
"""
# Author: Rob Austein
# Copyright (c) 2016, NORDUnet A/S
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# - Neither the name of the NORDUnet nor the names of its contributors may
# be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from os import urandom
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256, HMAC
parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter)
parser.add_argument("-p", "--pin",
default = "YouReallyNeedToChangeThisPINRightNowWeAreNotKidding",
help = "PIN plaintext before PBKDF2 processing")
parser.add_argument("-i", "--iterations",
type = int,
default = 10000,
help = "PBKDF2 iteration count")
parser.add_argument("-d", "--derived-key-length",
type = int,
default = 64,
help = "length of PBKDF2 output (must match libhal)")
args = parser.parse_args()
def HMAC_SHA256(pin, salt):
return HMAC.new(pin, pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */# Temporary sandbox for Python PKCS #8 hacks, probably integrate into
# test scripts, libhal.py, etc once have figured this out.
#
# Both PyCrpto and the Python ecdsa package have their own ASN.1, so
# why are we using yet another package? Because it's easier to
# understand, that's why. Perhaps once we've debugged this we'll
# recode it using one of the other packages to reduce external
# dependencies, but for now, pyasn1 wins on ease of debugging.
#
# Also see the "native" encode and decode routines in pyasn1, which
# supposedly encode and decode to built-in Python data types instead
# of the fancy types from the pyasn1 library. Might be simpler, but
# whole new mess so defer for now.
# RFC 5208: PKCS #8
# RFC 2313: PKCS #1.5 [rsa.c]
# RFC 5915: EC keys [ecdsa.c]
from pyasn1.type.univ import Sequence, SetOf, Integer, OctetString, ObjectIdentifier, BitString, Any
from pyasn1.type.namedtype import NamedTypes, NamedType, OptionalNamedType
from pyasn1.type.namedval import NamedValues
from pyasn1.type.tag import Tag, tagClassContext, tagFormatSimple, tagFormatConstructed
from pyasn1.type.constraint import SingleValueConstraint
from pyasn1.codec.der.encoder import encode as DER_Encode
from pyasn1.codec.der.decoder import decode as DER_Decode
from ecdsa import der as ECDSA_DER
from ecdsa.util import oid_ecPublicKey, encoded_oid_ecPublicKey
from ecdsa.keys import SigningKey
from ecdsa.curves import find_curve
class AlgorithmIdentifier(Sequence):
componentType = NamedTypes(
NamedType( "algorithm", ObjectIdentifier()),
OptionalNamedType( "parameters", Any()))
class AttributeTypeAndValue(Sequence):
componentType = NamedTypes(
NamedType( "type", ObjectIdentifier()),
NamedType( "value", Any()))
class Attribute(Sequence):
componentType = NamedTypes(
NamedType( "type", ObjectIdentifier()),
NamedType( "vals", SetOf(componentType = Any())))
# RFC 5208
class PrivateKeyInfo(Sequence):
componentType = NamedTypes(
NamedType( "version", Integer(namedValues = NamedValues(("v1", 0))) .subtype(subtypeSpec = Integer.subtypeSpec + SingleValueConstraint(0))),
NamedType( "privateKeyAlgorithm", AlgorithmIdentifier()),
NamedType( "privateKey", OctetString()),
OptionalNamedType( "attributes", SetOf(componentType = Attribute()) .subtype(implicitTag = Tag(tagClassContext, tagFormatConstructed, 0))))
class EncryptedPrivateKeyInfo(Sequence):
componentType = NamedTypes(
NamedType( "encryptionAlgorithm", AlgorithmIdentifier()),
NamedType( "encryptedData", OctetString()))
# RFC 2313
class RSAPrivateKey(Sequence):
componentType = NamedTypes(
NamedType( "version", Integer() .subtype(subtypeSpec = Integer.subtypeSpec + SingleValueConstraint(0))),
NamedType( "n", Integer()),
NamedType( "e", Integer()),
NamedType( "d", Integer()),
NamedType( "p", Integer()),
NamedType( "q", Integer()),
NamedType( "dP", Integer()),
NamedType( "dQ", Integer()),
NamedType( "u", Integer()))
# RFC 5915
class ECPrivateKey(Sequence):
componentType = NamedTypes(
NamedType( "version", Integer(namedValues = NamedValues(("ecPrivkeyVer1", 1))) .subtype(subtypeSpec = Integer.subtypeSpec + SingleValueConstraint(1))),
NamedType( "privateKey", OctetString()),
OptionalNamedType( "parameters", ObjectIdentifier() .subtype(explicitTag = Tag(tagClassContext, tagFormatSimple, 0))),
OptionalNamedType( "publicKey", BitString() .subtype(explicitTag = Tag(tagClassContext, tagFormatSimple, 1))))
# Test data, generated by OpenSSL
der_test_keys = dict(
ec_rfc5915 = '''
MHcCAQEEIFWaZOsQxLwZmIK4YAuf1d8S9Pnznvzcl9TjiMpvXkCYoAoGCCqGSM49
AwEHoUQDQgAEC/8vH5bL+3KNNF/NL+VmUKZQtjA59UsGtKP6FP4ZqFc3Y7Gie77/
lG1/L+s/6ircB1JkI8zaE3KYd7s+7IYIEQ==
'''.decode("base64"),
ec_pkcs8 = '''
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgVZpk6xDEvBmYgrhg
C5/V3xL0+fOe/NyX1OOIym9eQJihRANCAAQL/y8flsv7co00X80v5WZQplC2MDn1
Swa0o/oU/hmoVzdjsaJ7vv+UbX8v6z/qKtwHUmQjzNoTcph3uz7shggR
'''.decode("base64"),
rsa_rfc2313 = '''
MIIEpAIBAAKCAQEAx/N9ee3u6Z6qjw5waPhuUBYy7m6+kRfNYB8KSERGd5K2xD96
IeyvEv+xMDA2BQ3xOummL2yAjtMZ2N7Le37nfpvtzwVWqrOHzq7OWaw/pPl1N9Lq
VSQLPoxHw3TVe69QNPVu5SeumaOGXmzTIs1pr2yVBZD/i2KYiif3BO2SgoDx7g4s
cFdg/6YiDpKYbY/yx4YN6KJxDGMM6DE0Ih8hE68flJMSIbUWIaJZo0b7XPeE9zYU
zf93VLvuYIqWYMuwTw5TSUnzeRq6ALJpf90nObduJsYEPu/i4RFlxdm5WsmOb2Tu
F7JFesEdGeT9lCxxd3CI5YTItQIBWsx0AzCS/QIDAQABAoIBAQCmC7Zvwv9cUr8g
/cSr52L0bvrstlra8wFCiYRobwp10gilAHHUKlFZXa0vb1ns6J8jZVT0nQ5FjVkx
mBMzAzgLFEJwYOaP63ckVFZYcYqI3gBR0312JvCPiL8vuZ5vkC7zS75D3qhIPlwf
ng/YHu1dGLbIYJlWjxJN6NJh7Uh1xlZcm0WAJYhJpmMIZJv2abTS4GXw4SVOyMnd
tPEgEfrK/y2PsNUPwnby6LR1cE2rxOQtb6gNCov0AAiE0BsJeE7jXa2IEl6lKoBR
ChDMAeU53pJPlcYt7ZmAgyezuEfnr4kY5Rk/nTcwTxTpzQi7Dcth8QCRqfu4wXXj
QEN7b9cBAoGBAPNjRPc/Z89jYp1IDR+R5oi7YTsLzNAIlS/t9wgrujnVdsm00xos
dd+NwvjTi7wE0fV+7u5/W9ni3077JaBGBa9+nD0iB0PgAJW+tb8HUJXABQKoTA4m
yyiAHNHgarwc1uwr+yAYqvSj7aAvIcZeXgi3qxDXEOSKuk8n57/TpPMVAoGBANJP
/9/6zxd3PdogiP0nC+piJHstexk+l4WRqGWWuRG0VTIEfBk4dQfj/UwfmTcCQxAe
D0e9EoHeVOfsv4nfOfDhGC7jHLkLpNJbc5ttgr2sZ6qIouBJ8suMDte/zZze27aU
7epFqw0w9Y58fwRyP2u5ILYFcm+cWeplg9lY4rpJAoGBALzLs1Krn4YzDOr+Whe0
IITN/XVFCQIStk8wo2B2MwXrvTJoDx0Ngf4AxE4qIwmdH5T0erkMmB5jK1/j12MF
DiH874tIWyRenXWLMwZU0UDoa7qM/Do6A3uOLUzsbT8wi9M1pp5WJD6S7qBED0oG
J6FRf+QXQCZYKn9+b/nQXfKlAoGADwFuPEjk5cO4Qgv4OjfC/eIqwC8qjU6N+RW/
ciAi7ER1n6/6OsJwdzOpKvlGMUqUBl5esLuoymNWo4Wc1PV8aNdmplHGBt3x0KB9
yyUxIt9eNiixllcwX52KoZIp1XuBKbHOl9yIq9RGcPgpB+Qu6jy3PMV+uL/rGnJL
ygIxiyECgYAwSLLuxHKGcy+oZo1vxSQlY2gOkprqK9VwjAhxGuGlJftXrL/Dkbxs
GatW0bGAyQ+VPivPl8YYhs34NCA1t1pJKczcNbHEJFN57x6AtCbHFLWB91wY96yA
6y/Bgd45PoXryQl7+GdOAPyEYY3mq3R5vaozTraPrnD+61kpKVLJ/Q==
'''.decode("base64"),
rsa_pkcs8 = '''
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDH83157e7pnqqP
DnBo+G5QFjLubr6RF81gHwpIREZ3krbEP3oh7K8S/7EwMDYFDfE66aYvbICO0xnY
3st7fud+m+3PBVaqs4fOrs5ZrD+k+XU30upVJAs+jEfDdNV7r1A09W7lJ66Zo4Ze
bNMizWmvbJUFkP+LYpiKJ/cE7ZKCgPHuDixwV2D/piIOkphtj/LHhg3oonEMYwzo
MTQiHyETrx+UkxIhtRYholmjRvtc94T3NhTN/3dUu+5gipZgy7BPDlNJSfN5GroA
sml/3Sc5t24mxgQ+7+LhEWXF2blayY5vZO4XskV6wR0Z5P2ULHF3cIjlhMi1AgFa
zHQDMJL9AgMBAAECggEBAKYLtm/C/1xSvyD9xKvnYvRu+uy2WtrzAUKJhGhvCnXS
CKUAcdQqUVldrS9vWezonyNlVPSdDkWNWTGYEzMDOAsUQnBg5o/rdyRUVlhxioje
AFHTfXYm8I+Ivy+5nm+QLvNLvkPeqEg+XB+eD9ge7V0YtshgmVaPEk3o0mHtSHXG
VlybRYAliEmmYwhkm/ZptNLgZfDhJU7Iyd208SAR+sr/LY+w1Q/CdvLotHVwTavE
5C1vqA0Ki/QACITQGwl4TuNdrYgSXqUqgFEKEMwB5Tnekk+Vxi3tmYCDJ7O4R+ev
iRjlGT+dNzBPFOnNCLsNy2HxAJGp+7jBdeNAQ3tv1wECgYEA82NE9z9nz2NinUgN
H5HmiLthOwvM0AiVL+33CCu6OdV2ybTTGix1343C+NOLvATR9X7u7n9b2eLfTvsl
oEYFr36cPSIHQ+AAlb61vwdQlcAFAqhMDibLKIAc0eBqvBzW7Cv7IBiq9KPtoC8h
xl5eCLerENcQ5Iq6Tyfnv9Ok8xUCgYEA0k//3/rPF3c92iCI/ScL6mIkey17GT6X
hZGoZZa5EbRVMgR8GTh1B+P9TB+ZNwJDEB4PR70Sgd5U5+y/id858OEYLuMcuQuk
0ltzm22Cvaxnqoii4Enyy4wO17/NnN7btpTt6kWrDTD1jnx/BHI/a7kgtgVyb5xZ
6mWD2VjiukkCgYEAvMuzUqufhjMM6v5aF7QghM39dUUJAhK2TzCjYHYzBeu9MmgP
HQ2B/gDETiojCZ0flPR6uQyYHmMrX+PXYwUOIfzvi0hbJF6ddYszBlTRQOhruoz8
OjoDe44tTOxtPzCL0zWmnlYkPpLuoEQPSgYnoVF/5BdAJlgqf35v+dBd8qUCgYAP
AW48SOTlw7hCC/g6N8L94irALyqNTo35Fb9yICLsRHWfr/o6wnB3M6kq+UYxSpQG
Xl6wu6jKY1ajhZzU9Xxo12amUcYG3fHQoH3LJTEi3142KLGWVzBfnYqhkinVe4Ep
sc6X3Iir1EZw+CkH5C7qPLc8xX64v+sackvKAjGLIQKBgDBIsu7EcoZzL6hmjW/F
JCVjaA6Smuor1XCMCHEa4aUl+1esv8ORvGwZq1bRsYDJD5U+K8+XxhiGzfg0IDW3
WkkpzNw1scQkU3nvHoC0JscUtYH3XBj3rIDrL8GB3jk+hevJCXv4Z04A/IRhjear
dHm9qjNOto+ucP7rWSkpUsn9
'''.decode("base64"))
def decode_ecpoint(ecpoint):
return { "\x02": "compressed", "\x04": "uncompressed" }[ecpoint[0]], ecpoint[1:1+len(ecpoint)/2], ecpoint[1+len(ecpoint)/2:]
def dumpasn1(der):
from subprocess import call
from tempfile import NamedTemporaryFile
with NamedTemporaryFile() as f:
f.write(der)
f.flush()
call(("dumpasn1", "-aop", f.name))
if __name__ == "__main__":
show_manual_decode = False
ec_rfc5915 = DER_Decode(der_test_keys["ec_rfc5915"], ECPrivateKey() )[0]
ec_pkcs8 = DER_Decode(der_test_keys["ec_pkcs8"], PrivateKeyInfo())[0]
ec_pkcs8_privateKey = DER_Decode(str(ec_pkcs8["privateKey"]), ECPrivateKey() )[0]
rsa_rfc2313 = DER_Decode(der_test_keys["rsa_rfc2313"], RSAPrivateKey() )[0]
rsa_pkcs8 = DER_Decode(der_test_keys["rsa_pkcs8"], PrivateKeyInfo())[0]
rsa_pkcs8_privateKey = DER_Decode(str(rsa_pkcs8["privateKey"]), RSAPrivateKey() )[0]
print
print "EC RFC 5915"
print ec_rfc5915.prettyPrint()
if show_manual_decode:
print
compressed, Qx, Qy = decode_ecpoint(ec_rfc5915["publicKey"].asOctets())
print "version: ", ec_rfc5915["version"]
print "privateKey:", str(ec_rfc5915["privateKey"]).encode("hex")
print "parameters:", ec_rfc5915["parameters"]
print "publicKey: ", compressed
print " Qx: ", Qx.encode("hex")
print " Qy: ", Qy.encode("hex")
# This works, and lets .prettyPrint() display the ANY content properly,
# but it breaks some of the key hackery we do after all this display stuff.
#ec_pkcs8["privateKeyAlgorithm"]["parameters"] = DER_Decode(ec_pkcs8["privateKeyAlgorithm"]["parameters"])[0]
print
print "EC PKCS #8"
print ec_pkcs8.prettyPrint()
print ec_pkcs8_privateKey.prettyPrint()
if show_manual_decode:
print
compressed, Qx, Qy = decode_ecpoint(ec_pkcs8_privateKey["publicKey"].asOctets())
print "version: ", ec_pkcs8["version"]
print "privateKeyAlgorithm:", ec_pkcs8["privateKeyAlgorithm"][0]
print " ", DER_Decode(ec_pkcs8["privateKeyAlgorithm"]["parameters"])[0]
print "privateKey:"
print " version: ", ec_pkcs8_privateKey["version"]
print " privateKey:", str(ec_pkcs8_privateKey["privateKey"]).encode("hex")
print " parameters:", ec_pkcs8_privateKey["parameters"]
print " publicKey: ", compressed
print " Qx: ", Qx.encode("hex")
print " Qy: ", Qy.encode("hex")
print
print "RSA RFC 2313"
print rsa_rfc2313.prettyPrint()
if show_manual_decode:
print
print "version:", rsa_rfc2313["version"]
print " n:", rsa_rfc2313["n"]
print " e:", rsa_rfc2313["e"]
print " d:", rsa_rfc2313["d"]
print " p:", rsa_rfc2313["p"]
print " q:", rsa_rfc2313["q"]
print " dP:", rsa_rfc2313["dP"]
print " dQ:", rsa_rfc2313["dQ"]
print " u:", rsa_rfc2313["u"]
#rsa_pkcs8["privateKeyAlgorithm"]["parameters"] = DER_Decode(rsa_pkcs8["privateKeyAlgorithm"]["parameters"])[0]
print
print "RSA PKCS #8"
print rsa_pkcs8.prettyPrint()
print rsa_pkcs8_privateKey.prettyPrint()
if show_manual_decode:
print
print "version: ", rsa_pkcs8["version"]
print "privateKeyAlgorithm:", rsa_pkcs8["privateKeyAlgorithm"][0]
print "privateKey:"
print " version:", rsa_pkcs8_privateKey["version"]
print " n:", rsa_pkcs8_privateKey["n"]
print " e:", rsa_pkcs8_privateKey["e"]
print " d:", rsa_pkcs8_privateKey["d"]
print " p:", rsa_pkcs8_privateKey["p"]
print " q:", rsa_pkcs8_privateKey["q"]
print " dP:", rsa_pkcs8_privateKey["dP"]
print " dQ:", rsa_pkcs8_privateKey["dQ"]
print " u:", rsa_pkcs8_privateKey["u"]
# Generate PKCS #8 from ECPrivateKey and check against static data
p8 = PrivateKeyInfo()
ec = ECPrivateKey()
ec["version"] = ec_rfc5915["version"]
ec["privateKey"] = ec_rfc5915["privateKey"]
ec["publicKey"] = ec_rfc5915["publicKey"]
p8["version"] = 0
p8["privateKeyAlgorithm"] = AlgorithmIdentifier()
p8["privateKeyAlgorithm"]["algorithm"] = "1.2.840.10045.2.1"
p8["privateKeyAlgorithm"]["parameters"] = ObjectIdentifier(ec_rfc5915["parameters"])
p8["privateKey"] = DER_Encode(ec)
der = DER_Encode(p8)
#print; dumpasn1(der)
#print; dumpasn1(der_test_keys["ec_pkcs8"])
print; print "Reencoded PKCS #8 {} static data".format("matches" if der == der_test_keys["ec_pkcs8"] else "doesn't match")
# Try doing same thing with ecdsa package ASN.1 utilities.
sk = SigningKey.from_der(der_test_keys["ec_rfc5915"])
vk = ECDSA_DER.encode_bitstring("\x00\x04" + sk.get_verifying_key().to_string())
ec = ECDSA_DER.encode_sequence(ECDSA_DER.encode_integer(1),
ECDSA_DER.encode_octet_string(sk.to_string()),
ECDSA_DER.encode_constructed(1, vk))
p8 = ECDSA_DER.encode_sequence(ECDSA_DER.encode_integer(0),
ECDSA_DER.encode_sequence(encoded_oid_ecPublicKey,
sk.curve.encoded_oid),
ECDSA_DER.encode_octet_string(ec))
print; print "ECDSA-library PKCS #8 encoding {} pyasn1 PKCS #8 encoding".format("matches" if p8 == der_test_keys["ec_pkcs8"] else "doesn't match")
# Generate ECPrivateKey from PKCS #8 and check against static data
ec = ECPrivateKey()
ec["version"] = ec_pkcs8_privateKey["version"]
ec["privateKey"] = ec_pkcs8_privateKey["privateKey"]
ec["parameters"] = str(DER_Decode(ec_pkcs8["privateKeyAlgorithm"]["parameters"])[0])
ec["publicKey"] = ec_pkcs8_privateKey["publicKey"]
der = DER_Encode(ec)
#print; dumpasn1(der)
#print; dumpasn1(der_test_keys["ec_rfc5915"])
print; print "Reencoded PKCS #8 {} static data".format("matches" if der == der_test_keys["ec_rfc5915"] else "doesn't match")
# Paranoia: Make sure we really can load the RFC 5915 we just generated.
sk = SigningKey.from_der(der)
print; print "ECDSA Python library parse of reencoded PKCS #8 data: {!r}".format(sk)
# Same thing with ecdsa package ASN.1 utilities.
car, cdr = ECDSA_DER.remove_sequence(der_test_keys["ec_pkcs8"])
assert cdr == ""
version, cdr = ECDSA_DER.remove_integer(car)
assert version == 0
car, ec = ECDSA_DER.remove_sequence(cdr)
oid, cdr = ECDSA_DER.remove_object(car)
assert oid == oid_ecPublicKey
oid, cdr = ECDSA_DER.remove_object(cdr)
curve = find_curve(oid)
assert cdr == ""
car, cdr = ECDSA_DER.remove_octet_string(ec)
assert cdr == ""
car, cdr = ECDSA_DER.remove_sequence(car)
assert cdr == ""
version, cdr = ECDSA_DER.remove_integer(car)
assert version == 1
privkey, cdr = ECDSA_DER.remove_octet_string(cdr)
tag, car, cdr = ECDSA_DER.remove_constructed(cdr)
assert tag == 1
assert cdr == ""
pubkey, cdr = ECDSA_DER.remove_bitstring(car)
assert cdr == ""
assert pubkey[:2] == "\x00\x04"
sk = SigningKey.from_string(privkey, curve)
print; print "ECDSA-library PKCS #8 decoding {} pyasn1 PKCS #8 decoding".format(
"matches" if der == sk.to_der() else "doesn't match")