[tor-bugs] #13042 [Tor]: torspec isn't very clear about the encodings used for `onion-key` and `signing-key`
Tor Bug Tracker & Wiki
blackhole at torproject.org
Tue Sep 2 23:52:27 UTC 2014
#13042: torspec isn't very clear about the encodings used for `onion-key` and
`signing-key`
-------------------------+-------------------------------------------------
Reporter: isis | Owner:
Type: defect | Status: new
Priority: normal | Milestone:
Component: Tor | Version:
Resolution: | Keywords: torspec, leekspin, stem, bridgedb,
Actual Points: | tor-descriptors
Points: | Parent ID:
-------------------------+-------------------------------------------------
Comment (by nickm):
Replying to [ticket:13042 isis]:
> Currently, in `dir-spec.txt`, it is specified that:
>
> {{{
> "signing-key" NL a public key in PEM format
>
> [Exactly once]
>
> The OR's long-term identity key. It MUST be 1024 bits.
> }}}
>
> and
>
> {{{
> "onion-key" NL a public key in PEM format
>
> [Exactly once]
>
> This key is used to encrypt CREATE cells for this OR. The key
MUST be
> accepted for at least 1 week after any new key is published in a
> subsequent descriptor. It MUST be 1024 bits.
> }}}
>
> However, according to
[https://gitweb.torproject.org/stem.git/commitdiff/e0095fbe54759c45cbf6d1b120d2b17b47a0ec21
this commit] added to Stem in #5810, verifying signatures created with the
`signing-key` isn't so easy. With that code, Stem is able to verify
descriptor signatures created by Tor, yet not
[https://gitweb.torproject.org/user/isis/leekspin.git/blob/HEAD:/leekspin/generator.py#l89
those created by Leekspin], which clearly means the spec is unclear on
this matter (and Leekspin is Doing It Wrong).
>
> My current understanding after looking at `crypto_pk_public_checksig()`
in Tor, the OpenSSL source, and Stem's signature verification code above
is that the `signing-key` and `onion-key` are formatted as follows:
>
> 1. OpenSSL PEM-encoded export of public halves of keys.
> 2. The PEM-encoded keys are stripped of their `----BEGIN...` and
`-----END...` headers.
> 3. The keys are then PKCS!#1 padded.
> 4. Next, the PKCS!#1-padded, PEM-encoded raw keys are encoded as an
ASN.1 DER sequence.
> 5. That ASN.1 DER sequence is then base64 encoded.
> 6. Finally, the `-----BEGIN...` and `-----END...` headers are stuck
back on the keys, and they are shoved into the descriptor.
>
>
> Questions:
>
> * Is the above understanding of the order of encodings correct?
That sounds pretty weird. It's just whatever PEM_write_bio_RSAPublicKey
does. That's documented in the "pem" manpage for openssl. (in the
openssl distro as doc/crypto/pem.pod). That seems to be implemented in
terms of a bunch of macros in crypto/pem/pem.h, which then use
i2d_RSAPublicKey. Those are just doing asn.1 encoding/decoding, as
implemented in crypto/rsa/rsa_ameth.h
No, it's not exactly pretty, but asn.1 never is.
> * Which version of PCKS!#1? Any version? Anything newer than v1.5?
Only v2.0?
Do they encode RSA public keys differently?
> * I understand the use of PKCS!#1 to protect against padding attacks,
but doesn't [https://en.wikipedia.org/wiki/Adaptive_chosen-
ciphertext_attack#Practical_attacks Bleichenbacher's attack] still work
against PKCS!#1 v1.0?
That's not relevant for key encoding, surely?
Also, it's not relevant for signatures; only encryption.
> * Why aren't we using the PKCS!#1 probabilistic signature schemes
(RSASSA-PSS/EMSA-PSS) used in PKCS!#1 v2.0?
PSS wasn't widely available enough when we started making server
descriptors. The reason we don't change is that we don't use RSA to sign
anything secret and then reveal the signature without the secret.
> * For the signatures, the descriptor document "through the newline on
the `router-signature` line" is PKCS!#1-padded, then digested. Does this
include the newline character?
Yes.
> * Also, the spec is unclear as to whether
> 1. the ''descriptor document'' is PKCS!#1-padded, then digested,
then signed,
> or
> 2. the descriptor document is digested, then signed, and the
''signature'' is PKCS!#1-padded.
Digest, then pad, then sign. (Padding a signature does no good and
protects against nothing.)
> {{{
> "router-signature" NL Signature NL
>
> [At end, exactly once]
>
> The "SIGNATURE" object contains a signature of the PKCS1-padded
> hash of the entire router descriptor, taken from the beginning of
the
> "router" line, through the newline after the "router-signature"
line.
> The router descriptor is invalid unless the signature is
performed
> with the router's identity key.
> }}}
>
> * Is it any specific type of ASN.1 DER sequence?
>
> * Why are we using ASN.1? Does it protect against something? It just
seems to send parsers to early graves. Why can't we just do the base64
encoding after PKCS!#1?
I think you might be confusing encoding and padding? We don't use ASN.1
in generating signatures; we're only using it for key encoding.
Similarly, we don't use PKCS1 padding for encoding keys; we only use it
the signatures here.
The reason "why" is "that's how openssl likes to encode public keys."
> * ''Why? Oh why? Cthulhu fhtagn... Why? The insanity...''
You write a protocol, maintain it for a decade, and this kind of thing
seems bound to happen...
Or to be more constructive ...This is the perfect opportunity for you to
review proposals 220 and 228, since they are about to add new signature
types, and look for ambiguities. (224 too if you're feeling brave) ;)
--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/13042#comment:1>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online
More information about the tor-bugs
mailing list