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

From: "Gould, James" <[email-masked]>
Date: Thu, 28 Jan 2021 16:26:04 +0000

Barry,

Thank you for your review and feedback.  I respond to your feedback embedded below.  I will publish draft-ietf-regext-secure-authinfo-transfer-06  once these items are agreed to.  Let me know if you agree with the proposed updates below or if you have any additional proposed changes.

Thanks,

-- 

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/21/21, 4:29 PM, "Barry Leiba" <[email-masked]> wrote:

    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

JG - Your proposed abstract looks good to me.  Thanks for working up the summary.  

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

JG - Done

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

JG - Done

    — 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

JG - Done

    — 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

JG - Agreed, I believe the calculations were there initially and should have been removed after the later revisions.

    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?

JG - Yes, including the normative SHOULD makes sense.  

       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.

JG - Done

    — 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.

JG - I don't believe we can or should provide guidance on the expected time frame of the TTL, since it can greatly differ based on the criticality of the domain name, the transfer policy of the losing registrar, and the relationship between the losing registrar, the gaining registrar, and the registrant.    

    — 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.

JG - Done, added the reference for both places where SHA-256 is mentioned; although I referenced FIPS 180-4 (https://csrc.nist.gov/publications/detail/fips/180/4/final) instead of 180-3.  

       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.)

JG - There were lots of references to empty and non-empty authorization information.  I used the "an empty authorization information value" and "a non-empty authorization information value" throughout with a few exceptions where the word value was used more than once, like the sentence that you referenced above.  I changed the sentence above as you proposed, since using the term value for a third time does not read very well.  

       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

    END

JG - Yes, I believe the expansion is in line with the intent.  I went ahead and made the update.

    — 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

JG - Yes, I believe your proposal reads better.  I went ahead and made the change.

       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”).

JG - Yes, you are correct.  I made the update.

    — 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.

JG - The <domain:authInfo> must contain either a <domain:pw> element or a <domain:ext> element, where the <domain:pw> element is relevant to this draft and is indicated by referencing "password-based authorization information".  The same also applies to RFC 5733 with the use of the <contact:pw> element for password-based authorization information.  To make this explicit, the first sentence of section 4 "Secure Authorization Information" can be updated to "The authorization information in the EPP RFCs ([RFC5731] and [RFC5733]) that support transfer use password-based authorization information. ([RFC5731] with the <domain:pw> element and [RFC5733] with the <contact:pw> element)".  
.  
    — 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.)

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.  

    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.

JG - Thanks for the background.  In this case it's not a user generating the value for later use to authenticate, but a system that generates a randomized value that is used to process a transfer.      

       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

JG - Thanks for making it clearer.  I'll incorporate the recommended change.  The same change will also be made in section 5.1.

    — 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.

JG - Server is the same thing as registry in the EPP RFCs and is consistently used, so I believe we should stick with "server policy" in place of "registry policy".  The draft is slightly different in that it explicitly calls out registrant, registrar, and registry (section 2) to define the handling and use of the authorization information in transfers.  I looked for all references to "server policy" versus "registry policy" and all instances but one used "server policy".  The exception is in section 6.2 "Transition Phase 2 - Storage", where the section explicitly references registry at the start and therefore uses "registry policy" in the final step.  My preference is to leave it as is, where "server policy" is used generically throughout unless a section explicitly references registry, which is the case for the section 6.2 " Transition Phase 2 - Storage".  Does this make sense?    

       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.

JG - The poll message applies in both cases of an immediate transfer and a pending transfer, since the gaining registrar is part of the transaction and not the losing registrar.  The losing registrar needs to be notified of the transfer.  I believe the requirement for the poll message should stay as a separate sentence.

    — 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”?

JG - Good catch, the "49" will be updated to "128".  

    -- 
    Barry

---

From: Barry Leiba <[email-masked]>
Date: Thu, 28 Jan 2021 11:48:13 -0500

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.

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.

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.

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.

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?

Barry