Subject: [regext] AD review of draft-ietf-regext-secure-authinfo-transfer-05

From: Barry Leiba <[email-masked]>
Date: Thu, 21 Jan 2021 16:29:01 -0500

Thanks for the publication request.  It's taken me a while to get the
review finished, but here it is, below.  Please feel free to push back
on things you don't agree with, and let's have the discussion.  In any
case, I'm sure we'll need a revised I-D, so I'm going to put this in
"Revised I-D Needed" substate.

The Abstract has too much unnecessary detail, which belongs in the
Introduction but doesn’t benefit the Abstract.  The purpose of the
Abstract is to make it clear what the document is about, so readers
know whether it’s relevant to them.  Explaining all the issues, and
what has or hasn’t been fully considered before… those aren’t needed.
I suggest the following, but feel free to adjust it appropriately.  If
you really think the extra detail is needed *in the Abstract*, push
back on this comment and let me know why.

NEW
   The Extensible Provisioning Protocol (EPP), in RFC 5730, defines the
   use of authorization information to authorize a transfer.  Object-
   specific, password-based authorization information (see RFC 5731 and
   RFC 5733) is commonly used, but raises issues related to the security,
   complexity, storage, and lifetime of authentication information.
   This document defines an operational practice, using the EPP RFCs,
   that leverages the use of strong random authorization information
   values that are short-lived, not stored by the client, and stored
   by the server using a cryptographic hash that provides for secure
   authorization information that can safely be used for object
   transfers.
END

I would split the first paragraph of the Introduction, making a new
paragraph at “This document”.

— Section 1.1 —
Please use the new BCP 14 boilerplate and add a normative reference to RFC 8174.

— Section 4 —

   For the
   authorization information to be secure it must be a strong random
   value and must have a short time-to-live (TTL).

I would prefer not to have variations on the phrasing: better to stay
consistent.  So, to be consistent with what’s in 4.1:

NEW
   For the
   authorization information to be secure it must be generated
   using a strong random value and have a short time-to-live (TTL).
END

— Section 4.1 —

   For authorization information to be secure, it MUST be generated
   using a secure random value.  The authorization information is
   treated as a password, where according to [RFC4086] a high-security
   password must have at least 49 bits of randomness or entropy.  The
   required length L of a password, rounded up to the largest whole
   number, is based on the set of characters N and the desired entropy
   H, in the equation L = ROUNDUP(H / log2 N).  With a target entropy of
   49, the required length can be calculated after deciding on the set
   of characters that will be randomized.  The following are a set of
   possible character sets and the calculation of the required length.

   Calculation of the required length with 49 bits of entropy and with
   the set of all printable ASCII characters except space (0x20), which
   consists of the 94 characters 0x21-0x7E.

   ROUNDUP(49 / log2 94) =~ ROUNDUP(49 / 6.55) =~ ROUNDUP(7.48) = 8

   Calculation of the required length with 49 bits of entropy and with
   the set of case-insensitive alphanumeric characters, which consists
   of 36 characters (a-z A-Z 0-9).

   ROUNDUP(49 / log2 36) =~ ROUNDUP(49 / 5.17) =~ ROUNDUP(9.48) = 10

   Considering the age of [RFC4086], the evolution of security
   practices, and that the authorization information is a machine-
   generated value, the recommendation is to use at least 128 bits of
   entropy.  The lengths are recalculated below using 128 bits of
   entropy.

The two calculations and the introductory paragraphs that go with them
seem entirely unnecessary: you make the calculations and then
immediately say “But we’re not going to use those, so here are the
real calculations.”  I strongly suggest just going straight to the
128-bit version, thus:

NEW
   For authorization information to be secure, it MUST be generated
   using a secure random value.  The authorization information is
   treated as a password, where according to [RFC4086] a high-security
   password must have at least 49 bits of randomness or entropy.  The
   required length L of a password, rounded up to the largest whole
   number, is based on the set of characters N and the desired entropy
   H, in the equation L = ROUNDUP(H / log2 N).  Given a target entropy,
   the required length can be calculated after deciding on the set
   of characters that will be randomized.

   Considering the age of [RFC4086], the evolution of security
   practices, and that the authorization information is a machine-
   generated value, the recommendation here is to use at least 128 bits
   of entropy.  The lengths are calculated below using that value.
END

Also, should the “recommendation” of at least 128 bits be upgraded to
a BCP 14 key word (perhaps changing “the recommendation here is to use
at least 128 bits” to “implementations SHOULD use at least 128 bits” ?
 If not, why not?

   the random number generator, the practices defined in [RFC4086] and
   section 4.7.1 of the NIST Federal Information Processing Standards
   (FIPS) Publication 140-2
   (https://csrc.nist.gov/publications/detail/fips/140/2/final) SHOULD
   be followed to produce random values that will be resistant to
   attack.

FIPS 140-2 needs to be listed in the normative references and cited
here as a reference (“[FIPS-140-2]” or some such).  Look at the
“[DSS]” reference in RFC 8446 to see how to do that, if you don’t know
how to cite an external reference.

— Section 4.2 —

Does it make sense to add a sentence that talks about some vaguely
expected time frame?  Nothing concrete, but are we talking about
minutes, hours, days, or weeks?  It might help to say something.

— Section 4.3 —

   1.  The authorization information MUST be stored by the registry
       using a strong one-way cryptographic hash, with at least a
       256-bit hash function such as SHA-256, and with a random salt.

You should have an informative reference to FIPS 180-3 (SHA) and a
citation to it here.  RFC 6234 has that reference if you need to look
at it.

   2.  An empty authorization information MUST be stored as an undefined
       value that is referred to as a NULL value.

Nit: “An” feels weird here.  I would start the sentence with “Empty”,
even though there’s “an” later in the sentence.  There are also other
instances of “an empty authorization information”, so please look for
them and remove “an” (but “an empty authorization information value”
is OK).  (If you disagree on this point… well, it is just a nit, and
we can see what the RFC Editor thinks.)

   5.  The plain text version of the authorization information MUST NOT
       be written to any logs by the registrar or the registry.

Does it make sense to expand on this, somewhat in this way?:

NEW
   5.  The plain text version of the authorization information MUST NOT
       be written to any logs by the registrar or the registry, nor
       otherwise recorded where it will persist beyond the transfer
       process.
END

— Section 4.4 —

   The unset authorization information is stored with a
   NULL (undefined) value.  Based on the requirement to store the
   authorization information using a strong one-way cryptographic hash,
   as defined in Section 4.3, a set authorization information is stored
   with a non-NULL hashed value.

This isn’t wrong, but I had to read it a couple of times to get it,
mostly because of reading “a set authorization information” in the
context of “a set OF authorization information”, rather than as
intended.  Does something like this work?:

NEW
   Authorization information that is unset is stored with a
   NULL (undefined) value.  Based on the requirement to store the
   authorization information using a strong one-way cryptographic hash,
   as defined in Section 4.3, authorization information that is set is
   stored with a non-NULL hashed value.
END

   2.  An empty input authorization information value MUST NOT match any
       authorization information value.

I think this needs “that is set” at the end (or “any set authorization”).

— Section 5.1 —

   C:        <domain:authInfo>
   C:          <domain:pw/>
   C:        </domain:authInfo>

Interesting.  I would have taken the document text to mean that this should be:

   C:        <domain:authInfo>
   C:        </domain:authInfo>

or

   C:        <domain:authInfo/>

Is the “<domain:pw/>” element required?  If so, it’s probably worth
clarifying that in the text.

— Section 5.2 —

   The registry SHOULD validate
   the randomness of the authorization information based on the length
   and character set required by the registry.  For example, a registry
   that requires 20 random printable ASCII characters except space
   (0x20), should validate that the authorization information contains
   at least one upper case alpha character, one lower case alpha
   character, and one non-alpha numeric character.  If the authorization
   information fails the randomness validation, the registry MUST return
   an EPP error result code of 2202.

Oof!
Random is random, and if we’re looking for a 12-character string
“eobphbevwjcg” is as “random” as “eoB$hbevwjcg” is.  I’m not happy
with forcing password strings to pass arbitrary and very dubious
randomness tests, especially with a “MUST reject with an error”
requirement, and it’s likely that a good, randomly generated password
will fail this test.  You already have requirements here for
generating strong passwords.  And in reality, you can’t stop
implementations from generating crappy passwords that all happen to
begin with “Aa@“ if that’s what they want to do.  I don’t mind a
non-normative statement that such checks might be performed, as an
alert to existing implementation situations.  But making it a
normative requirement doesn’t seem right.

(And apart from that, it seems strange to say SHOULD validate… and
then MUST reject, which I won’t do if I didn’t validate in the first
place.)

Anecdote:
A system I used to use back in the 1980s had a set of rules, which
included a ban on repeated substrings, substrings that are month
names, and stuff like that (because people used to use “mypwaug” in
August and then change it to “mypwoct” in October).  One of my
colleagues picked quite a good password, given the single-case
8-character limit at the time: “ttwbjan”, which are the initials of a
line of lyrics from a song from “West Side Story”.  The system refused
to accept it.  He told me, and we both hated that.  I’ve been scarred
ever since.

   Any EPP object extension that
   supports setting the authorization information with a
   "eppcom:pwAuthInfoType" element, can have an empty authorization
   information passed, such as [RFC5731] and [RFC5733].

Can I tell you how many times I read this, trying to figure out how
RFCs 5731 and 5733 represented empty authorization information, before
I figured out that the sentence is ordered wrong?

NEW
   Any EPP object extension that
   supports setting the authorization information with a
   "eppcom:pwAuthInfoType" element, can have empty authorization
   information passed.  Examples of such extensions are [RFC5731]
   and [RFC5733].
END

— Section 5.4 —

   Whether the transfer occurs immediately or is pending is
   up to server policy.

I would say “up to registry policy”, yes?  At the least, “up to
registry policy as implemented by the server”, to make it clear which
server owns the policy… but, really, it shouldn’t be a server-specific
issue, but a registry-specific one.

   transfer is pending, the registry MUST return the EPP success result
   code of 1001.  The losing registrar MUST be informed of a successful
   transfer request using an EPP poll message.

Should this be “code of 1001 and the losing”?  Surely that last
sentence only applies to the pending case.

— Section 9 —

   The server SHOULD define policy
   related to the length and set of characters that are included in the
   randomization to target the desired entropy level, with the
   recommendation of at least 49 bits for entropy.

But we’re recommending at least 128 bits in Section 4.1.  Shouldn’t we
say “128” here, rather than “49”?

-- 
Barry

---

From: "Gould, James" <[email-masked]>
Date: Thu, 28 Jan 2021 19:01:59 +0000

Barry,

Thanks again for reviewing the responses.  I provide my responses below on the "verify randomness" item.

-- 
 
JG

James Gould
Fellow Engineer
[email-masked] <applewebdata://13890C55-AAE8-4BF3-A6CE-B4BA42740803/[email-masked]>

703-948-3271
12061 Bluemont Way
Reston, VA 20190

Verisign.com <http://verisigninc.com/>

On 1/28/21, 11:48 AM, "Barry Leiba" <[email-masked]> wrote:

    Thanks, Jim.  We're good on everything except the "verify randomness"
    stuff, so let's just talk about that one a little more.

    > JG - Since the authorization information is generated by a system and
    > not by a user, it's important for the server to validate that it is
    > random, which is why it's defined using a normative SHOULD.  Use of
    > randomized authorization information passwords is key to the approach,
    > and a basic randomization check can and should be done by the server.
    > The reason for the SHOULD and MUST pattern is to make the check a
    > recommendation with a SHOULD, and if a randomness check is implemented
    > it's assumed that an error will be returned and that result code MUST
    > be 2202 and not some other result code.  The MUST is associated the
    > choice of the result code and not whether or not to return an error,
    > where I can't think of a scenario where a server would not return an
    > error if the randomization check is implemented and fails.  I believe
    > the SHOULD and MUST are applicable and needed in the draft.

    First, I question the premise that "it's important for the server to
    validate that it is random": the specification says that it MUST be
    random, and gives additional guidance for making that happen.  I
    disagree that it's important, or even desirable to attempt to confirm
    that, and I don't believe it's even possible to do such validation
    meningfully.

JG - The random generated authinfo password is a requirement for the client in implementing the draft, but I believe that it's important for the server to do some level of validation that the client is randomly generating the password to meet the security elements of the practice.  The server can do basic validation based on the length of the password, the chosen character set, and math.  If the password is 20 or 25 characters based on the different character sets defined in the draft to meet the 128 bits of entropy, the server can validate that characters in different character groups (at least one lowercase letter, at least on uppercase letter, at least one number, at least one special character) using probability.  What is the probability that a randomly generated password of 20 character contain all lowercase characters?  The draft doesn't define the method for servers to use, but providing some level of validation is warranted.  

    Second, I don't believe that the validation mechanism proposed works,
    and I contend that it's not reasonable.  As I say, it's entirely
    possible for a properly created random password to fail the checks
    that are proposed here.

JG - I believe that some basic validations is possible using the chosen character set, password length, character groups and probability.    

    Third, I passed this by Ben Kaduk, and he agrees... so I would expect
    to get pushback from the Sec ADs on this point if it goes forward like
    this.

JG - I would like to understand why from a security perspective recommending for the server to do validation that the client is using a random password is an issue.  I view it as an important security element, where some basic validation can be done safely with a low probably of failure.  

    If there were truly a reasonable way to do a randomness check, I would
    be in favour of it.  It's not, because if you ask me to select a
    random five-digit number, "12345" is just as likely to come up as
    "39186", and just because my program generated "12345" doesn't mean
    it's broken.

JG - The approach is to look at groups of characters existing in the generated password based on the length and the character set chosen.  Let's say you decide to have a 5 digit password, what is the probability that the random password contains the digit 1?   The probability is (1 - ((10 - 1)/10)^5) = 40.9%.  How about the probability that the random generated password contains either a digit 1 or 2, (1 - ((10 - 2)/10)^5) = 67.2%.  If you increase the length and adjust the character group, the probability will greatly increase.  Let's get to a larger character set and length based on the entropy calculations in the draft.  What is the probability that a 25 character randomly generated password with a 36 character set (a-z A-Z 0-9) contains at least one digit (0-9).  That would be (1 - ((36 - 10)/36)^25) = 99.97%.  The server can also look at the sequence of characters to validate randomness.  The point is that it is possible using the password policies and probability to implement some level of randomness validation in the server.  It's not a MUST in the draft but a SHOULD to recommend that the server should do some level of validation.       

    Would you like us to add Ben and Roman to the discussion, so that we
    get their thoughts and suggestions now, rather than waiting for the
    formal IESG Evaluation?

If you feel that it would help out, I support bringing them in. 

    Barry