a Secarta project ...

HTTPsec Authentication Protocol

[ View as multiple pages ]

Abstract

A public key authentication scheme for HTTP transactions, specifying a minimal HTTP extension for mutual authentication, message origin authentication, message sequence integrity, content integrity, and content ciphering.

Status

This document is a draft specification which may undergo minor changes, both normative and presentational.

Document Date:
2006-09-29
Editor
Stephan Fowler: stephan.fowler@secarta.com
Copyright
Copyright 2005 Secarta, all rights reserved. Copyright and IPR notices.

Table of Contents


1. Introduction

This specification describes a public key authentication scheme for HTTP transactions. It provides a minimal HTTP extension for mutual authentication and message origin authentication. It offers integrity protection of a defined set of HTTP message headers, message sequence integrity, content integrity, and content ciphering.

This scheme is designed to fit into the generic authentication framework of RFC2616 [HTTP], as exploited in RFC2617 [HTTP-Authentication].

1.1. Editorial Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this specification are to be interpreted as described in RFC2119 [KEYWORDS]

1.2. Terms

"Peer" refers generically to either of the two principals acting as requester and responder in an HTTP message exchange. Formally, a peer is a logical entity that can invoke its associated private key for the purpose of that exchange. Note that user-agents and/or servers may act as (or for) a multitude of logically distinct peers, and are thus not themselves considered necessarily equivalent to those peers.

"Message" refers generically to an HTTP message, be it a request or a response.

"requester" refers to the peer sending a request message and receiving a response message.

"responder" refers to the peer receiving a request message and sending a response message.

"Encryption" is used in relation to asymmetric key operations, whereas the term "cipher" is used in relation to symmetric key operations.

1.3. Identifiers

The identifier for this scheme is "httpsec/1.0". This literal features in protocol headers and in various protocol computations.

The identifier for the Content-Encoding defined for message-body ciphering is "x-httpsec/1.0-cipher".

2. Summary

This specification describes a concrete syntax for a public key authentication scheme for HTTP transactions. It provides a minimal HTTP extension for mutual authentication and message origin authentication, via the integrity protection of a defined set of HTTP message headers. It offers message sequence integrity, forward secrecy, and optionally content integrity and content ciphering.

It is intended for application in situations where credential-based schemes are inappropriate for architectural reasons or are considered too weak, and also where message-layer and/or application-layer security requirements are not fulfilled by transport-layer or network-layer security protocols. It is not intended as a substitute for lower- or higher-layer security protocols, and indeed may be found to usefully coexist with these.

2.1. Authentication Model

This scheme uses public keys for the mutual authentication of peers. More precisely, it allows one peer to authenticate a message that purports to originate from another peer.

As with all public key authentication schemes, acceptance of the authenticity of a peer is equivalent to establishing that the peer possesses the private key paired with a certain public key. The authentication model is thus predicated on the assumption that the authenticator can correctly associate a public key with the peer it is authenticating. Accordingly, a candidate purporting to be such a peer is considered authentic if it can demonstrate its ability to invoke the associated private key. This document does not address the process by which a public key is associated (correctly or not) with a peer. The protocol is intended to be able to integrate with any number of such mechanisms, from "leap of faith" type schemes such as employed by SSH, to trust-based schemes such as PKI style certification.

2.2. Peer Identifiers

A peer has an associated identifier. This acts as a logical reference to the peer's public key. These peer identifiers are literals that are purposefully opaque in this specification. The combination of an identifier and the public key associated with it is the "authenticated peer" from the perspective of an other peer that authenticates it.

In some use-cases, the public key of one peer is considered to be known (or retrievable in a trusted manner) by a second peer that requires it in order to authenticate the first peer. The first peer's identifier is thus a reference that the second peer may use to retrieve the appropriate public key, for instance from a trusted local store. In other use-cases, for example those that require a bootstrapping capability, public keys are exchanged within the protocol itself.

2.3. Protocol Operation

This protocol enables, and depends on, the establishment of a shared-secret arrangement between the requester and the responder. The protocol has two distinct stages; "initialization" and "continuation". Initialization establishes a shared-secret between the requester and responder via a request/response transaction between the two. It is within this initialization transaction that the public keys of the peers are employed for mutual authentication.

Subsequent continuation transactions carry conventional message payloads. They reference the shared secret established by the initialization stage, and depend on both peers' knowledge of it for their security features. No temporal constraint is placed on the validity of the shared-secret arrangement, which may be chosen independently by either peer to be anything from very short lived to essentially permanent. (The initialization stage could in fact be effected by another process entirely outside of this specification.)

The responder is first authenticated in the initialization stage by the use of digital signatures. The requester is authenticated in each continuation transaction by the use of message authentication codes. This asymmetry allows the requester to authenticate the responder before sending it any data, while keeping all public-key and other key-exchange operations within the single initialization transaction. This mitigates the state-management requirements and ensures that computationally expensive operations are avoided in subsequent continuation messages, of which there may be an arbitrary number.

2.3.1. Initialization

The requester begins the initialization stage by sending a request containing its initialize parameters. The responder returns with a response containing its initialize parameters. Both these messages contain the peer's identifier, ephemeral Diffie-Hellman key, and optionally their authentication public key. See Initialization Request and Initialization Response for the form these messages take.

This initialization transaction establishes an authenticated shared-secret arrangement between both peers, indexed by a token chosen by the responder. Forward secrecy is ensured by the ephemeral Diffie-Hellman shared-secret exchange. Both peers identically derive temporary message authentication keys and cipher keys from the shared-secret, to be employed in the protection of subsequent continuation messages.

Whereas the protocol mandates certain conditions under which these temporary keys must be discarded, either peer may choose to discard them according to rules of their own, for instance based on elapsed time since last usage.

2.3.2. Continuation

Continuation requests carry a token to reference a previously initialized shared-secret arrangement. All continuation messages carry message authentication codes to determine message origin authenticity, partial sequence integrity, and optionally entity-body integrity. Continuation messages may employ optional message body ciphering at the discretion of the sending peer. In all other respects, continuation messages are conventional HTTP messages. See Continuation Request and Continuation Response for the form these messages take.

The responder may at any stage prompt initialization (or re-initialization) by returning a challenge response. See Challenge Response for the form this message takes.

3. Protocol Messages

All protocol parameters are carried in existing HTTP message headers. The Authorization request header [HTTP][ Section 14.8] carries the requester's protocol parameters. The WWW-Authenticate response header [HTTP][ Section 14.47] carries the responder's responder's parameters. These are the headers implied wherever reference is made in this document to the passing of protocol parameters by the respective peers.

The HTTP header definitions in this specification use the augmented Backus-Naur form of [HTTP] [Section 2.1], and use these common terminators:

base64          = *(4base64-char) [base64-terminal]
base64-char     = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" |
                  "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" |
                  "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" |
                  "Y" | "Z" |
                  "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" |
                  "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" |
                  "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" |
                  "y" | "z" |
                  "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
                  "8" | "9" | "+" | "/"
base64-terminal = (2base64-char "==") | (3base64-char "=")

decimal         = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
        

Definitions of individual header directives are given in the Protocol Directives section.

3.1. Initialization Messages

Messages containing an initialize directive assert that the sending peer is providing initialization parameters. Successful initialization requires an initialization request and an associated initialization response.

3.1.1. Initialization Request

The Authorization header [HTTP][ 14.8] in protocol initialization requests has the following form:

"Authorization: httpsec/1.0 initialize, "
 1#(  id
   |  dh
   | [certificate] 
   |  url
   |  group
   |  nonce )
   
id          = "id=" <URI>
dh          = "dh=" base64
certificate = "certificate=" <URI>
url         = "url=" <URI>
group       = "group=" <string-no-whitespace>
nonce       = "nonce=" base64

Example message:

HEAD http://alice.example.com/foobar.txt HTTP/1.1
Authorization: httpsec/1.0 initialize
    id=bob.example.com
    dh=clW9y2X5Vy+5+Ncv5lAI3W9y2X5Vgfe4y+5+Ncv5l...
    certificate=http://bob.example.com/my-cert
    url=http://alice.example.com/foobar.txt
    group=rfc3526#14
    nonce=7iqgkzgfdIe0HN35r6met2579yxetyerty7MZW...

(For legibility, the example's protocol header is extended over multiple lines, as per [HTTP][4.2]. Additionally, the values of some directives are lengthy and have therefore been abbreviated; their terminating ellipsis "..." would NOT appear in the actual value.)

An initialization request has a HEAD method [HTTP][ Section 9.4], unless it carries a certificate payload in the message entity-body (see certificate section) in which case it has a POST method [HTTP][ Section 9.5].

Its Request-URI [HTTP][ Section 5.1.2] is typically be that of a protected resource hosted by the responder and ultimately desired by the requester, but this is not normative.

3.1.2. Initialization Response

The WWW-Authenticate header [HTTP][ 14.47] in protocol initialization responses has the following form:

"WWW-Authenticate: httpsec/1.0 initialize, "
 1#(  id
   |  dh
   | [certificate]
   |  token
   |  auth
   |  signature )
     
token       = "token=" <string-no-whitespace>
id          = "id=" <URI>
dh          = "dh=" base64
certificate = "certificate=" <URI>
auth        = "auth=" base64
signature   = "signature=" base64

Example message:

HTTP/1.1 401 Authorization Required
Expires: Thu, 11 Aug 2005 18:20:42 GMT
Cache-Control: no-transform
WWW-Authenticate: httpsec/1.0 initialize
    id=alice.example.com
    dh=+NcclW9y2I3W9X5Vy+5v5lAy4X56y+Ncrwrtv5lqe...
    certificate=http://alice.example.com/my-cert
    token=mCa5tx1vKBY
    auth=vpCNmx7MZ7iqgkzIe0HWwfyrOMeqwg0TdbpwefI...
    signature=2pX3SNgzWkV3w0W9y2X5V23hhy+5b8DQmo...

(For legibility, the example's protocol header is extended over multiple lines, as per [HTTP][4.2]. Additionally, the values of some directives are lengthy and have therefore been abbreviated; their terminating ellipsis "..." would NOT appear in the actual value.)

3.2. Continuation Messages

Messages containing a continue directive assert that the message is protected by security features that derive from a previously initialized shared-secret arrangement. A continuation transaction constitutes a continuation request and an associated continuation response.

A continuation message MUST pass Message Validation or be immediately discarded by the peer that receives it.

3.2.1. Continuation Request

The Authorization header [HTTP][ 14.8] in protocol continuation requests has the following form:

"Authorization: httpsec/1.0 continue, " 
 1#(  token
   |  url
   |  count
   |  mac
   | [digest] )
                     
token  = "token=" <string-no-whitespace>
url    = "url=" <URI>
count  = "count=" 1*decimal
mac    = "mac=" base64
digest = "digest=" base64

Example message:

GET http://alice.example.com/foobar.txt HTTP/1.1
Authorization: httpsec/1.0 continue
    token=mCa5tx1vKBY
    url=http://alice.example.com/foobar.txt
    count=1
    mac=zhHPRbxqf3KSMQpjCnpDQmyBnoqiNDMQLjRtMjxUcM=

(For legibility, the example's protocol header is extended over multiple lines, as per [HTTP][4.2].)

3.2.2. Continuation Response

The WWW-Authenticate header [HTTP][ 14.47] in protocol continuation responses has the following form:

"WWW-Authenticate: httpsec/1.0 continue, "
 1#(  count
   |  mac
   | [digest] )

count  = "count=" 1*decimal
mac    = "mac=" base64
digest = "digest=" base64

Example message:

HTTP/1.1 200 OK
Date: Thu, 11 Aug 2005 18:20:48 GMT
Expires: Thu, 11 Aug 2005 18:20:48 GMT
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 1234
Cache-Control: no-transform
Content-Encoding: x-httpsec/1.0-cipher
WWW-Authenticate: httpsec/1.0 continue
    count=2
    mac=VplDHX3SNgzWkLKgZkjZ+I5wvImOHAMptVSc/Abttps=
    digest=V3w0W9y2X5Vy+5+Ncv5lAI3rb8qMlGzrOh9zjHXRHbk= 

<entity-body ciphertext bytes>

(For legibility, the example's protocol header is extended over multiple lines, as per [HTTP][4.2].)

3.3. Challenge Messages

The challenge response is an assertion by the responder that the requested resource is protected by HTTPsec. It is an invitation, made by responder to requester, to make a subsequent initialization request.

In the handling of a Challenge Response, the requester SHOULD employ a method of limiting the extent of potential deadlock from a repeated series of challenge, for instance limiting them to an arbitrary number such as 3.

3.3.1. Challenge Response

The WWW-Authenticate header [HTTP][ 14.47] for challenge responses has the following form:

"WWW-Authenticate: httpsec/1.0 challenge, "
 1#(  id
   | [certificate] )

id          = "id=" <URI>
certificate = "certificate=" <URI>

Example message:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: httpsec/1.0 challenge
    id=alice.example.com
    certificate=http://alice.example.com/my-cert

(For legibility, the example's protocol header is extended over multiple lines, as per [HTTP][4.2].)

3.4. Message Flow

This section details the conditions which regulate how requests and responses are matched, and which HTTP status codes [HTTP][ Section 10] are set by the responder.

4. Protocol Directives

All protocol parameters feature as directives in initialization messages and continuation messages. These directives are detailed in this section.

4.1. id

The id directive in an initialization request is the requester's Peer Identifier. From the responder's perspective, this acts as a logical reference to the requester's public-key.

The id directive in an initialization response or a challenge response is the responder's Peer Identifier. From the requester's perspective, this acts as a logical reference to the responder's public-key.

4.2. dh

The dh directive in an initialization request and an initialization response provides the sending peer's ephemeral Diffie-Hellman public key.

This directive is calculated as follows:

dh = g ^ dh-private MOD p  

where the following apply:

  • g is the generator of the Diffie-Hellman group. The latter is chosen by the requester and identified by the group directive in the initialization request.
  • p is the prime modulus of the Diffie-Hellman group.
  • private-dh is a random integer in the range: 2...q-2 where q is the subgroup order of the Diffie-Hellman group. Note that q = (p-1)/2 for all the MUST IMPLEMENT groups.

The value of private-dh is chosen by the sending peer from a source of cryptographic-quality randomness, and is treated as strictly private. It SHOULD be generated anew for each new initialization, in which case it SHOULD be discarded immediately after the computation of the shared secret. However if computational resources are limited it MAY be reused across multiple initializations, but this will affect the effective extent of the protocol's claim to forward secrecy.

4.3. certificate

The optional certificate directive in an initialization request and an initialization response provides the sending peer's certificate containing its (purported) authentication public key. The directive may also be employed for informational purposes in a challenge response. In some use-cases a peer's public key is prior-knowledge from the perspective of the other peer, and thus the certificate directive is not required.

If employed, its value MUST be a valid URI as specified in [URI] Section 3. Certificates provided by the certificate directive MUST be in X509 [X509] certificate format to allow (if required) the use of a Public Key Infrastructure.

Implementations MAY support either or all of the following:

  1. transmission of the X509 certificate itself using a "data" URI scheme. [DATA]. For example:
    certificate=data:application/x-x509-user-cert;base64,MIGfMA0GCSqGSI...
    
    (the value is lengthy and has therefore been abbreviated; the terminating ellipsis "..." would NOT appear in an actual value)
  2. provision of a URL for retrieving the X509 certificate. For example:
    certificate=http://alice.example.com/my-cert
    
  3. use of the bespoke URI "this:entity-body" to indicate that the X509 certificate is carried in the message entity-body. For example
    certificate=this:entity-body
    

In all cases, the Mine-Type of the certificate payload MUST be "application/x-x509-user-cert". Certificates in entity-bodies may optionally have the PEM specified header, footer and line breaks.

Note that in the first usage, the certificate payload itself features in the Initialization Transcript and its presence in the initialisation stage is thus authenticated by the signature. This may be considered favourable in some use-cases.

4.4. url

The url directive in an initialization request and a continuation request is the the absolute URL of that request. The latter is duplicated in this directive because proxies are legitimately allowed to change the Request-Line in transit.

The responder MUST confirm that the value of this directive is equivalent to the absolute URL implied by the request's Request-Line [HTTP] and Host [HTTP] header. Equivalence conditions for URLs are given in [URI] Section 6.

4.5. group

The group directive in an initialization request is the identifier of a Diffie-Hellman modular exponential group, as chosen by the requester. It's value MUST NOT contain whitespace.

Any or all of the following identifiers and their associated groups MAY be implemented:

"rfc3526#14"  ; group #14 defined in [MODP]
"rfc3526#15"  ; group #15 defined in [MODP]
"rfc3526#16"  ; group #16 defined in [MODP]
"rfc3526#17"  ; group #17 defined in [MODP]
"rfc3526#18"  ; group #18 defined in [MODP]

Other identifiers may be also defined.

4.6. nonce

The nonce directive in an initialization request allows the requester to send a random value to the responder. This acts as an authentication challenge to the responder, who is challenged to posses the correct private key in order to create a valid signature directive in the initialization response.

This value is a base64 encoded 256 bit cryptographic-quality random value, which MUST be generated afresh by the requester for each new initialization.

4.7. auth

The auth directive in an initialization response allows the responder to send an encrypted random value to the requester. This acts as an authentication challenge to the requester. The random value auth-secretis encrypted in the requester's public key, yet features unencrypted in the shared secret which must be identically known to both parties for the authentication success of subsequent continuation messages. The requester is thus challenged to posses the correct private key to decrypt the value of the auth directive.

The auth directive is computed as follows:

auth = base64enc( ENC( public-key, auth-secret ) )

where the following apply:

  • base64enc() is base64 encoding, bytes to string.
  • ENC( k, pt ) is encryption according to the Encryption Scheme in public key k of plaintext pt.
  • public-key is the public key associated (subjectively, by the responder) with the requester.
  • auth-secret is 256 bit cryptographic-quality random value generated by the responder, which MUST be generated afresh by the responder for each new initialization.

The requester decrypts the auth directive to retrieve the auth-secret value as follows:

auth-secret = DEC( private-key, base64dec( auth ) )

where the following apply:

  • base64dec() is base64 decoding, string to bytes.
  • DEC( k, ct ) is decryption according to the Encryption Scheme with private key k of ciphertext value ct.
  • private-key is the requester's private key.
  • auth-secret is 256 bit random value.

4.8. token

In an initialization response, the token directive is is an opaque reference to the newly initialized shared-secret arrangement. Its value is chosen by the responder, and MUST be unique within the responder's record of valid tokens. It's value MUST NOT contain whitespace, but its length or other characteristics are not otherwise constrained.

In a continuation Request the token directive is employed by the requester as a reference to a previously initialized shared-secret arrangement. From the perspective of both the request's requester and its responder, the referenced arrangement implies the MAC keys to create or validate mac directives, and implies the cipher keys for message body ciphering or deciphering.

4.9. signature

The signature directive in an initialization response is used to verify the integrity of all the initialization directives and thus allows the requester to authenticate the responder prior to making any continuation requests.

The signature directive is computed by the responder as follows:

signature = base64enc( SIGN( private-key, init-transcript ) )

where the following apply:

  • base64enc() is base64 encoding, bytes to string.
  • SIGN(k,m) is the signature over string m using private key k according to the Signature Scheme.
  • private-key is the responder's authentication key private key.
  • init-transcript is a concatenation of all the initialization directives, computed according to the Initialization Transcript section.

The signature directive is validated by the requester as follows:

VALIDATE( public-key, init-transcript, base64dec( signature ) )

where the following apply:

  • base64dec() is base64 decoding, string to bytes.
  • VALIDATE(k,m,s) is the validation of a signature s over a string m using public key k, according to the Signature Scheme.
  • signature is the value of the received directive.
  • public-key is the public key associated (subjectively, by the requester) with the responder. Note that this may or may not be equivalent the public key implied by the certificate directive, depending on the trust mechanism employed by the requester.
  • init-transcript is a concatenation of all the initialization directives, computed according to the Initialization Transcript section.

4.10. count

The count directive is a sequence counter for continuation messages. This directive allows the detection of message replays and provides partial message sequence integrity. It is also required for the production of unique initialization vectors for message body ciphering.

The value of the count directive is a decimal number. In a request, it MUST be greater than zero and less than (2^128 - 1). In a response, it MUST be greater than one and less than or equal to (2^128 - 1).

The following constraints apply to this directive in continuation messages containing identical token directive values. Messages with identical or out-of-sequence count directive values MUST be rejected by the receiving peer. Peers MUST validate the count directive in each received message to establish uniqueness and correct sequence. Each peer is required to maintain a local record of the value of the count directive employed in the last continuation message that it sent. The validity constraints and logic for setting this directive differ slightly from the perspectives of the two peers:

requester's perspective:
A received response MUST have a count value of N+1, where N is the count value in the associated request.
requester's perspective:
A received request's count value N MUST be strictly greater than the count value that the responder sent in its last response. The response MUST be given a count value of N+1.

If a first request receives no response, the count directive in a second request that immediately follows should increment by (at least) 2, to allow for the fact that the unreceived response was nevertheless sent by the responder. In the case that the first request contained an "Expect: 100-continue" header [HTTP][14.20] the increment should be (at least) 3, as such requests may elicit two distinct responses.

4.11. mac

The mac directive in a continuation request and a continuation response is a keyed message authentication code computed on the values of protocol directives and specific HTTP headers present in that continuation transaction. It employs a MAC Key derived from the Shared Secret.

To create a message authentication code for a message either prior to sending it or in order to validate it, the appropriate computation is made as follows:

Request:
   mac = base64enc( HMAC( request-mac-key,  request-transcript  ) )

Response:
   mac = base64enc( HMAC( response-mac-key, response-transcript ) )

where the following apply:

The message authentication codes are formulated so as to provide the following:

  • message originator authentication;
  • integrity protection for the protocol directives of this specification;
  • integrity protection for the minimal set of HTTP headers designated as "non-modifiable" by intermediate caches [HTTP][ 13.5.2]. These headers are Content-Location, Content-MD5, ETag, Last-Modified, Expires, Content-Range, and Content-Type;
  • integrity protection for the message entity-body, if accompanied by a digest directive.

The sender of a message computes and provides the message authentication code for that message. To validate it, the recipient of the message also computes its message authentication code and compares the received value with the computed value. If (1) they are strictly equal, and (2) the digest directive (if present) is confirmed to indeed equal the hash of the message entity-body, then the above authentication characteristics are considered to be established. If not, the message MUST be rejected. This two stage process permits computationally inexpensive invalidity checks to be performed before embarking on the potentially expensive process of computing the digest over an arbitrary length entity-body.

4.12. digest

The the optional digest directive in a continuation request or a continuation response is a hash digest of the message entity-body. It's role is to enable message entity-body authentication: its value is an input to the computation of the mac directive (via the appropriate message transcript). This directive SHOULD be present in any continuation message for which it is feasible to calculate a hash digest of the entity-body (including, trivially, all those with an empty entity-body).

The value of the digest directive is a hash of the entity-body, computed using the Hash Algorithm. The hash MUST be computed on the entity-body as manifest after all encodings declared in the Content-Encoding [HTTP][ 14.11] header (including the cipher encoding with the identifier "x-httpsec/1.0-cipher" defined in the Message Body Ciphering section) and before Transfer-Encoding [HTTP][ 14.41].

The absence of the digest directive implies that the message entity-body is not authenticated. This may be the case if the entity-body cannot be hashed for some reason by the message sender, for instance if it is a stream of indeterminate length.

The value of the digest directive MUST be base64 encoded. For empty message bodies, it is the following constant (being the Base64 representation of the hash of zero bytes):

47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=

5. Other Headers

This specification impacts on certain other HTTP header field definitions, as detailed in this section.

5.1. Content-Encoding

The Content-Encoding header [HTTP][ 14.11] MAY contain the value "x-httpsec/1.0-cipher" in its enumeration of applied encodings, to indicate that the message entity body is ciphered according to this specification - see the Message_Body_Ciphering section for details.

5.2. Cache-Control

The Cache-Control header [HTTP][ 14.9] MUST be present in every initialization response and continuation response. It MUST contain at minimum the no-transform directive [HTTP][ 14.9.5]. See the Cache Considerations section for additional discussion.

5.3. Expires

The Expires header [HTTP][ 14.21] MUST be present in every initialization response and continuation response. responses. Its value MUST be the system clock time, current at the time of the preparation of the response's WWW-Authenticate: httpsec/1.0 continue header. Whist the value of this header appears in the computation of the mac directive, it has no explicit role in message validation. See also the Cache Considerations section for additional discussion.

6. Protocol Computations

6.1. Algorithms

Wherever they are referred to in this specification, the cryptographic primitives defined in this section MUST be employed.

6.1.1. Hash Algorithm

SHA-256 [SHA].

6.1.2. Public Key Algorithm

RSA [PKCS#1] asymmetric key encryption. The modulus of key MUST be 1024 bits or greater.

6.1.3. Encryption Scheme

RSA Optimal Asymmetric Encryption Padding (RSAES-OAEP) [PKCS#1], using hash function SHA-1, mask generation function MGF1 (with SHA-1), and the empty-string for the "label" parameter.

Note: whereas SHA-256 is specified as the Hash Algorithm primitive for employment elsewhere in the protocol, the choice of the SHA-1 here is made for the following reasons:

  1. The potential cryptanalytic vulnerability of SHA-1 is not relevant in this context. The role of the hash algorithm in OAEP is merely to hash the label parameter which in this instance is a known constant.
  2. OAEP with SHA-1 is widely implemented.

6.1.4. Signature Scheme

RSA Probabilistic Signature Scheme (RSASSA-PSS) [PKCS#1], using hash function SHA-256, mask generation function MGF1 (with SHA-256), and salt length of 32 bytes.

6.1.5. Block Cipher

Advanced Encryption Standard [AES], 256 bit key length.

6.1.6. Block Cipher Mode

Cipher Block Chaining mode [CBC], with PKCS#5 [PKCS#5 ] padding, applied to the Block Cipher.

6.2. Header Canonicalization

The values of various HTTP headers [HTTP][ 4.2] other than the protocol headers also feature in protocol computations, notably the signature and message authentication codes. The values of these headers MUST first undergo the following canonicalization transformations, applied in strict order:

  1. Retrieve the header's literal US-ASCII encoded field-value, including any quotes;
  2. Remove all whitespace;
  3. Remove leading or trailing substrings consisting only of semicolons (";") and/or commas (",")
  4. Replace with a single semicolon (";") any internal substring that consists only of semicolons (";") and/or commas (",").

For example, the (albeit unlikely) header field-value ";foo,, ; bar;; foo bar;" becomes "foo;bar;foobar".

Note that this canonicalization is strictly a pre-processing step for the purpose of protocol computations only. It is not a constraint on the actual header field-values that may appear in a message.

6.3. Initialization Transcript

The initialization transcript is an input to signature creation and validation, and shared secret computations. It is itself computed as follows:

init-transcript =  
    "httpsec/1.0" || ":" ||
     id           || ":" ||   ; from request 
     dh           || ":" ||   ; from request 
     certificate  || ":" ||   ; from request 
     url          || ":" ||   ; from request 
     group        || ":" ||   ; from request 
     nonce        || ":" ||   ; from request 
     id           || ":" ||   ; from response 
     dh           || ":" ||   ; from response 
     certificate  || ":" ||   ; from response 
     token        || ":" ||   ; from response 
     auth         || ":" ||   ; from response       
     Expires                  ; from response

where the following apply:

  • The source of the values is indicated by the "from request" and "from response" annotations.
  • id, dh, certificate, url, group, token, and auth refer to the directives contained in the Initialization Messages. They are the directives' literal US-ASCII encoded values exactly as they appear in those headers.
  • Expires is the value of [HTTP][ 4.2] header of that name, having undergone canonicalization as detailed in the Header Canonicalization section.
  • All values including empty strings are delimited by colons with respect to their neighbouring values. If a specified protocol directive or header is not present in the message, its value is taken to be the empty string.

6.4. Continuation Request Transcript

The continuation request transcript is an input to mac directive creation and validation. It is itself computed as follows:

request-transcript =                 
    "httpsec/1.0"     || ":"
  || token            || ":"   
  || count            || ":"
  || url              || ":"
  || digest           || ":"
  || Method           || ":"
  || Content-MD5      || ":"
  || Content-Encoding || ":"
  || Content-Range    || ":"
  || Content-Type

where the following apply:

  1. All values are taken from the request.
  2. token, count, url, and digest refer to the protocol directives with those names. They are the directives' literal US-ASCII encoded values exactly as they appear in those headers.
  3. Method is the Method [HTTP][ 5.1.1] from the request's Request-Line [HTTP][ 5.1].
  4. Content-MD5, Content-Encoding, Content-Range, and Content-Type refer to [HTTP][ 4.2] headers. Their values MUST first undergo canonicalization as detailed in the Header Canonicalization section.

6.5. Continuation Response Transcript

The continuation response transcript is an input to mac directive creation and validation. It is itself computed as follows:

response-transcript = 
    "httpsec/1.0"     || ":"
  || token            || ":"   ; from request
  || count            || ":"
  || url              || ":"   ; from request
  || digest           || ":"
  || Method           || ":"   ; from request
  || Status-Code      || ":"
  || Content-Location || ":"
  || Content-MD5      || ":"
  || ETag             || ":"
  || Last-Modified    || ":"
  || Expires          || ":"
  || Content-Encoding || ":"
  || Content-Range    || ":"
  || Content-Type

where the following apply:

  1. Values are taken from the response, unless indicated by the "from request" annotation.
  2. token, count, url, and digest refer to the protocol directives with those names. They are the directives' literal US-ASCII encoded values exactly as they appear in those headers.
  3. Method is the Method [HTTP][ 5.1.1] from the request's Request-Line [HTTP][ 5.1].
  4. Status-Code is the three digit Status Code [HTTP][ 6.1.1] from the response's Status-Line [HTTP][ 6.1].
  5. Content-Location, Content-MD5, ETag, Last-Modified, Expires, Content-Encoding, Content-Range, and Content-Type refer to [HTTP][ 4.2] headers. Their values MUST first undergo canonicalization as detailed in the Header Canonicalization section.

6.6. Shared Secret

The security of the protocol depends on the requester and responder establishing an (authenticated) shared secret. Continuation messages employ keys that are derived from this secret value.

The value shared-secret is computed as follows:

shared-secret = H(H( dh-shared-secret || auth-secret || init-transcript ))

where the following apply:

  • dh-shared-secret is calculated by the requester as follows:
    dh-shared-secret = dh ^ dh-private MOD p          
    
    where dh is from the initialization response, dh-private is the requester's private Diffie-Hellman value (see dh ) and p is the prime modulus of the Diffie-Hellman group chosen by the requester.
  • dh-shared-secret is calculated by the responder as follows:
    dh-shared-secret = dh ^ dh-private MOD p
    
    where dh is from the initialization request, dh-private is the responders's private Diffie-Hellman value (see dh ) and p is the prime modulus of the Diffie-Hellman group identified by the group directive in the initialization request.
  • auth-secret is the 256 bit random value generated by the responder. It is passed in encrypted form to the requester via the auth directive in the initialization response.
  • init-transcript is a concatenation of all the initialization directives, computed according to the Initialization Transcript section.
  • H(H()) is the Hash Algorithm iteratively applied twice.

6.7. Keys

From the Shared Secret, both peers derive identical MAC keys and Cipher Keys. Since the Shared Secret is static throughout the lifetime of a particular shared secret arrangement, the keys may be computed once from the shared-secret by each peer and stored for the lifetime of that arrangement. The shared-secret SHOULD be discarded immediately thereafter.

6.7.1. MAC Keys

The MAC keys for computing mac directives are produced as follows:

request-mac-key  = H(H( shared-secret || "request MAC key"  ))

response-mac-key = H(H( shared-secret || "response MAC key" ))

where the following apply:

  • String literals are ASCII without length or zero-termination;
  • shared-secret is computed according to the Shared Secret section.
  • H(H()) is the Hash Algorithm iteratively applied twice.

6.7.2. Cipher Keys

The keys required for message body ciphering are computed as follows:

request-cipher-key  = H(H( shared-secret || "request cipher key"  ))

response-cipher-key = H(H( shared-secret || "response cipher key" ))

where the following apply:

  • String literals are ASCII without length or zero-termination.
  • shared-secret is computed according to the Shared Secret section.
  • H(H()) is the Hash Algorithm iteratively applied twice.

6.8. Message Body Ciphering

Message entity-body ciphering may be be applied to any continuation message, at the discretion of the sending peer. If entity-body ciphering is applied, this MUST be indicated by the presence of the "x-httpsec/1.0-cipher" identifier in the enumeration of applied encodings declared by the Content-Encoding header. The order of operations is "cipher-then-authenticate", i.e. if used ciphering MUST be applied before the digest computation.

The ciphering of messages whose entity-body is empty will cause the entity-body to become non-empty as an artifact of padding scheme specified in the Block Cipher Mode. This should be taken into consideration when preparing messages for which it is illegal to have an entity body, such as GET requests, HEAD requests, and HEAD responses.

It is important to note that message entity-body ciphering in the absence of message authentication provides no detection of tampering during message transport. Entity-bodies are "ciphered but not authenticated" if they declare "x-httpsec/1.0-cipher" in the Content-Encoding header, but have no digest directive. This outcome SHOULD be restricted to circumstances where it is unfeasible to compute the digest hash, for instance when the entity-body is a stream of indeterminate length.

Request entity-bodies are enciphered and deciphered as follows:

Encipher:
   <body-cipher> = ENCIPHER-MODE( request-cipher-key, IV, <body-plain> )

Decipher:
   <body-plain>  = DECIPHER-MODE( request-cipher-key, IV, <body-cipher> )

where:
   IV = ENCIPHER( request-cipher-key, Bytes16( count ) )

Response entity-bodies are enciphered and deciphered as follows:

Encipher:
   <body-cipher> = ENCIPHER-MODE( response-cipher-key, IV, <body-plain> )

Decipher:
   <body-plain>  = DECIPHER-MODE( response-cipher-key, IV, <body-cipher> )

where:
   IV = ENCIPHER( request-cipher-key, Bytes16( count ) )

The following are defined and apply to both requests and responses:

  • request-cipher-key and response-cipher-key are as derived in the section Cipher Keys.
  • count is the numerical value implied by the count directive of the message being enciphered/deciphered.
  • Bytes16(x) is the value x encoded with leading zeros in exactly 16 bytes, most significant bits first, most significant byte first.
  • ENCIPHER(k,b) is the block enciphering function employing this specification's Block Cipher, using key k, applied to input block b. Lengths are as follows: k is 32 bytes, and b is 16 bytes.
  • ENCIPHER-MODE(k,iv,t) is the chained enciphering function employing this specification's Block Cipher Mode, using key k, initialization vector iv, applied to input text t. Lengths are as follows: k is 32 bytes, n is 16 bytes, t is of arbitrary length.
  • DECIPHER-MODE(k,iv,t) is the chained deciphering function employing this specification's Block Cipher Mode, using key k, initialization vector iv, applied to input text t. Lengths are as follows: k is 32 bytes, n is 16 bytes, t is of arbitrary length.
  • <body-plain> is the plaintext bytes of the message entity-body, as manifest after all encoding declared in the Content-Encoding [HTTP][ 14.11] header are applied.
  • <body-cipher> is the ciphertext bytes of the message entity-body, as manifest before any encodings declared in the Transfer-Encoding [HTTP][ 14.41] header are applied.

7. Message Validation

Validity conditions are given in this section for all protocol messages. Messages MUST satisfy all their respective conditions. The conditions are presented in suggested processing order determined by their increasing computational burden. The failure of any condition should immediately cause processing to terminate and the message to be discarded.

7.1. Initialization Request Validation

An initialization request message MUST meet all the following conditions to be considered valid by the responder that receives it:

  • The header is well-formed according to the Initialization Request section.
  • The url directive satisfies its equivalence condition.
  • The dh directive meets these conditions:
    • dh > 1
    • dh < p
    • dh ^ q MOD p = 1
    where p and q are from the Diffie-Hellman group indicated by the accompanying group directive.
  • The certificate directive, if present and if considered by the responder, provides a public key that is valid according to the Public Key Algorithm specification, notably regarding minimum key size.
  • The certificate directive, if present and if considered by the responder, satisfies locally determined validation constraints, typically with respect to installed certification authority root certificates.

7.2. Initialization Response Validation

A initialization response message MUST meet all the following conditions to be considered valid by the requester that receives it:

  1. The header is well-formed according to the Initialization Response section.
  2. The dh directive meets these conditions:
    • dh > 1
    • dh < p
    • dh ^ q MOD p = 1
    where p and q are from the Diffie-Hellman group indicated by the group directive in the initialization request.
  3. The certificate directive, if present and if considered by the requester, provides a public key that is valid according to the Public Key Algorithm specification, notably regarding minimum key size.
  4. The certificate directive, if present and if considered by the requester, satisfies locally determined validation constraints, typically with respect to installed certification authority root certificates.
  5. The signature directive value is valid. See signature section for details of the validation procedure.

7.3. Continuation Request Validation

A continuation request message MUST meet all the following conditions to be considered valid by the responder that receives it:

  1. The header is well-formed according to the Continuation Request section.
  2. The token directive references an existing shared secret arrangement.
  3. The url directive satisfies its equivalence condition.
  4. The count directive satisfies its uniqueness conditions.
  5. The mac directive's value equals the result of the re-computation over the message, using the request MAC key indexed by the token directive.
  6. If the digest directive is present, its value equals the result of hashing the entity-body according to this specification's Hash Algorithm.

A request that fails validation SHOULD cause the responder to flush all state associated with the shared secret arrangement indexed by the token directive, notably the MAC keys and Cipher keys.

7.4. Continuation Response Validation

A continuation response message MUST meet all the following conditions to be considered valid by the requester that receives it:

  1. The header is well-formed according to the Continuation Response section.
  2. The count directive satisfies the sequence and uniqueness conditions.
  3. The mac directive's value equals the result of the re-computation over the message, using the response MAC key indexed by the token stated in the associated request.
  4. If the digest directive is present, its value equals the result of hashing the entity-body according to this specification's Hash Algorithm.

A response that fails validation SHOULD cause the requester to flush all state associated with the shared secret arrangement indexed by the token directive in the associated request, notably the MAC keys and Cipher keys.

8. Cache Considerations

Implementers should be aware of how authenticated transactions interact with proxy caches. The HTTP/1.1 [HTTP] [ 14.8] specifies that when a shared cache has received a request containing an Authorization header and a response from relaying that request, it MUST NOT return that response as a reply to any other request.

Note also that whereas the HTTP/1.1 specification presents three exceptions to this rule, none of these exceptions are applicable to the authentication scheme here described. This is a result of the per-message uniqueness constraints introduced by various protocol directives.

Consequently, to make the non-cacheability of messages explicit the Expires response header [HTTP][ 14.21] MUST be set by the responder to the current system clock time, during the preparation of a response's "WWW-Authenticate: httpsec/1.0 continue" header directives. This is necessary for subsequent response validation, as the value of the Expires response header features in the computation of mac directives.

Also, the requirement that the no-transform directive [HTTP][ 14.9.5] MUST be set in a mandatory Cache-Control response header [HTTP][ 14.9] enforces specific modification constraints on transparent proxies that apply to certain headers - see [HTTP][ 13.5.2].

9. Security Considerations

This entire specification discusses a secure authentication system that protects HTTP messages transmitted across an untrusted network.

10. References

Normative references:

AES
FIPS 197. Specification for the Advanced Encryption Standard (AES) National Institute of Standards and Technology. November 2001.
http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
CBC
SP 800-38A. Recommendation for Block Cipher Modes of Operation. Morris Dworkin. December 2001.
http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C.pdf
DATA
RFC 2397. The "data" URL scheme. L. Masinter. August 1998.
http://www.ietf.org/rfc/rfc2397.txt
HMAC
RFC 2104. HMAC: Keyed-Hashing for Message Authentication. H. Krawczyk, M. Bellare, R. Canetti. February 1997.
http://www.ietf.org/rfc/rfc2104.txt
HTTP
RFC 2616. Hypertext Transfer Protocol -- HTTP/1.1. J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee. June 1999.
http://www.ietf.org/rfc/rfc2616.txt
HTTP Authentication
RFC 2617. HTTP Authentication: Basic and Digest Access Authentication. J. Franks, P. Hallam-Baker, J. Hostetler, S. Lawrence, P. Leach, A. Luotonen, L. Stewart. June 1999
http://www.ietf.org/rfc/rfc2617.txt
KEYWORDS
RFC 2119. Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. March 1997.
http://www.ietf.org/rfc/rfc2119.txt
MODP
RFC 3526. More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)
http://www.ietf.org/rfc/rfc3526.txt
PKCS#1
PKCS #1 v2.1. PKCS #1 v2.1: RSA Cryptography Standard.
ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
PKCS#5
PKCS #5 v2.0. PKCS #5 v2.0 Password-Based Cryptography Standard
ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc
SHA
FIPS PUB 180-2. Secure Hash Standard.
http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
URI
RFC 3986. Uniform Resource Identifiers (URI): Generic Syntax. T. Berners-Lee, R. Fielding, L. Masinter. August 1998.
http://www.ietf.org/rfc/rfc2396.txt
URL
RFC 1738. Uniform Resource Locators (URL). T. Berners-Lee, L. Masinter, and M. McCahill. December 1994.
http://www.ietf.org/rfc/rfc1738.txt
X509
RFC 2459. Internet X.509 Public Key Infrastructure Certificate and CRL Profile. R. Housley, W. Ford, W. Polk, D. Solo
http://www.ietf.org/rfc/rfc2459.txt

11. Editor Address

Stephan Fowler
secarta.com
Ferroners' House
Shaftesbury Place
London EC2Y 8AA
T +44 20 7796 2527
F +44 20 7796 3539

Email: stephan.fowler@secarta.com