[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