mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 03:22:48 -05:00
cmdgen: add a --dump option.
Also spelled '-O text', this takes a public or private key as input, and produces on standard output a dump of all the actual numbers involved in the key: the exponent and modulus for RSA, the p,q,g,y parameters for DSA, the affine x and y coordinates of the public elliptic curve point for ECC keys, and all the extra bits and pieces in the private keys too. Partly I expect this to be useful to me for debugging: I've had to paste key files a few too many times through base64 decoders and hex dump tools, then manually decode SSH marshalling and paste the result into the Python REPL to get an integer object. Now I should be able to get _straight_ to text I can paste into Python. But also, it's a way that other applications can use the key generator: if you need to generate, say, an RSA key in some format I don't support (I've recently heard of an XML-based one, for example), then you can run 'puttygen -t rsa --dump' and have it print the elements of a freshly generated keypair on standard output, and then all you have to do is understand the output format.
This commit is contained in:
@ -163,17 +163,41 @@ def make_argword(arg, argtype, fnname, argindex, to_preserve):
|
||||
"Can't convert {}() argument {:d} to {} (value was {!r})".format(
|
||||
fnname, argindex, typename, arg))
|
||||
|
||||
def unpack_string(identifier):
|
||||
retwords = childprocess.funcall("getstring", [identifier])
|
||||
childprocess.funcall("free", [identifier])
|
||||
return re.sub(b"%[0-9A-F][0-9A-F]",
|
||||
lambda m: valbytes([int(m.group(0)[1:], 16)]),
|
||||
retwords[0])
|
||||
|
||||
def unpack_mp(identifier):
|
||||
retwords = childprocess.funcall("mp_dump", [identifier])
|
||||
childprocess.funcall("free", [identifier])
|
||||
return int(retwords[0], 16)
|
||||
|
||||
def make_retval(rettype, word, unpack_strings):
|
||||
if rettype.startswith("opt_"):
|
||||
if word == b"NULL":
|
||||
return None
|
||||
rettype = rettype[4:]
|
||||
if rettype == "val_string" and unpack_strings:
|
||||
retwords = childprocess.funcall("getstring", [word])
|
||||
return unpack_string(word)
|
||||
if rettype == "val_keycomponents":
|
||||
kc = {}
|
||||
retwords = childprocess.funcall("key_components_count", [word])
|
||||
for i in range(int(retwords[0], 0)):
|
||||
args = [word, "{:d}".format(i)]
|
||||
retwords = childprocess.funcall("key_components_nth_name", args)
|
||||
kc_key = unpack_string(retwords[0])
|
||||
retwords = childprocess.funcall("key_components_nth_str", args)
|
||||
if retwords[0] != b"NULL":
|
||||
kc_value = unpack_string(retwords[0]).decode("ASCII")
|
||||
else:
|
||||
retwords = childprocess.funcall("key_components_nth_mp", args)
|
||||
kc_value = unpack_mp(retwords[0])
|
||||
kc[kc_key.decode("ASCII")] = kc_value
|
||||
childprocess.funcall("free", [word])
|
||||
return re.sub(b"%[0-9A-F][0-9A-F]",
|
||||
lambda m: valbytes([int(m.group(0)[1:], 16)]),
|
||||
retwords[0])
|
||||
return kc
|
||||
if rettype.startswith("val_"):
|
||||
return Value(rettype, word)
|
||||
elif rettype == "int" or rettype == "uint":
|
||||
|
Reference in New Issue
Block a user