RFC 5746

Transport Layer Security (TLS) Renegotiation Indication Extension

πŸ“… published February 2010, from ietf

RFC 5746 πŸŽ€ Part 1 of 3

Okay bestie, let's get into it πŸ’– This is RFC 5746, published by the Internet Engineering Task Force (IETF) in February 2010. The title is "Transport Layer Security (TLS) Renegotiation Indication Extension" ✨. The authors are E. Rescorla of RTFM, Inc., M. Ray and S. Dispensa of PhoneFactor, and N. Oskov of Microsoft. It's a Standards Track document πŸ‘‘ with ISSN 2070-1721. It updates RFC 5246, RFC 4366, RFC 4347, RFC 4346, and RFC 2246. The header doesn't list anything it obsoletes.

Abstract

Okay so SSL and TLS renegotiation have a vulnerability 😭. An attacker sets up a TLS connection with the target server, injects whatever content they want, and then splices in a new TLS connection from a client. The server treats the client's first handshake as a renegotiation, so it believes the attacker's early data came from the same entity as the client's later data. This spec adds a TLS extension that cryptographically ties each renegotiation to the TLS connection it's happening over, which shuts this attack down πŸ”’πŸ”₯

Status of This Memo

This is an Internet Standards Track document 🌸

It's a product of the IETF, so it reflects the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). You can find more about Internet Standards in Section 2 of RFC 5741.

Info about the current status of this document, any errata, and how to send feedback is at http://www.rfc-editor.org/info/rfc5746 πŸ¦‹

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved ©️

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, found at http://trustee.ietf.org/license-info, as they stood on the publication date. Please read these carefully, because they spell out your rights and restrictions for this document πŸ“œ Any Code Components pulled out of this document have to include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They come with no warranty, as the Simplified BSD License describes.

Table of Contents

   1. Introduction ....................................................3
   2. Conventions Used in This Document ...............................4
   3. Secure Renegotiation Definition .................................4
      3.1. Additional Connection State ................................4
      3.2. Extension Definition .......................................5
      3.3. Renegotiation Protection Request Signaling Cipher
           Suite Value ................................................6
      3.4. Client Behavior: Initial Handshake .........................6
      3.5. Client Behavior: Secure Renegotiation ......................7
      3.6. Server Behavior: Initial Handshake .........................7
      3.7. Server Behavior: Secure Renegotiation ......................8
   4. Backward Compatibility ..........................................9
      4.1. Client Considerations ......................................9
      4.2. Client Behavior: Legacy (Insecure) Renegotiation ..........10
      4.3. Server Considerations .....................................10
      4.4. Server Behavior: Legacy (Insecure) Renegotiation ..........11
      4.5. SSLv3 .....................................................11
   5. Security Considerations ........................................12
   6. IANA Considerations ............................................13
   7. Acknowledgements ...............................................13
   8. References .....................................................13
      8.1. Normative References ......................................13
      8.2. Informative References ....................................13

1. Introduction ✨

Okay so TLS [RFC5246] lets either the client or the server kick off a renegotiation, which is a brand-new handshake that sets up fresh cryptographic parameters πŸ”„ Here's the problem: the new handshake runs using the parameters from the original handshake, but there's no cryptographic binding between the two. That gap is an opening for an attacker who can intercept the client's transport layer connection. They inject their own traffic as a prefix to whatever the client is doing with the server πŸ‘€ One version of this attack [Ray09] goes like this:

   Client                        Attacker                        Server
   ------                        -------                         ------
                                     <----------- Handshake ---------->
                                     <======= Initial Traffic ========>
   <--------------------------  Handshake ============================>
   <======================== Client Traffic ==========================>

So the attacker sets up a TLS connection to the server, maybe because they intercepted an initial connection from the client πŸ•΅οΈβ€β™€οΈ Then they send any traffic they want to the server. This could be several application layer requests and responses, or just a partial application layer request meant to prefix the client's data. In the diagram, that traffic is marked with == to show it's encrypted. Next, the attacker lets the client's TLS handshake go through to the server. The handshake is readable by the attacker, but it's encrypted over the attacker's TLS connection to the server. Once the handshake finishes, the client talks to the server using the new security parameters. The attacker can't read any of that, but the server thinks the attacker's early traffic, both sent and received, is the same as the client's πŸ™ˆ

If certificate-based client authentication is used, the server sees a stream of bytes. The first bytes are protected but not authenticated by TLS, and the later bytes are authenticated by TLS and bound to the client's certificate. Some protocols, HTTPS especially, don't split up the pre-authentication and post-authentication stages. They handle all the bytes the same way, so the server ends up thinking the early traffic belongs to the authenticated client identity 😱 Even without certificate-based authentication, plenty of attacks are possible where the attacker gets the server to accept their data as if it came from the client. For example, if HTTPS [RFC2818] is used with HTTP cookies [RFC2965], the attacker might be able to generate a request of their choice that's validated by the client's cookie πŸͺ

Some protocols, like IMAP or SMTP, have clearer transitions between the authenticated and unauthenticated phases. They also need the protocol state machine to be partly or fully reset at those transitions. If those rules are followed strictly, they can limit how well these attacks work. Unfortunately, TLS renegotiation has no requirement for state machine resets, so there's still a window of vulnerability πŸ’€ For instance, an attacker can prefix a command that writes to an area they can see with a command from the client that includes the client's password, which exposes the password to the attacker. (This exact attack doesn't work against challenge-response authentication schemes, but other attacks might.) Similar attacks work against SMTP too, and they don't necessarily need the attacker to have an account on the target server.

It's important to note that in both cases these attacks work because the client sends unsolicited authentication information without needing any specific data from the server over the TLS connection. Protocols that need a round trip to the server over TLS before the client sends anything sensitive are likely to be less vulnerable πŸ›‘οΈ

To prevent these attacks, you cryptographically bind renegotiation handshakes to the enclosing TLS cryptographic parameters. That lets the server tell renegotiation apart from initial negotiation, and it stops renegotiations from being spliced in between connections πŸ’… If an attacker tries to inject themselves the way described above, the cryptographic binding won't match, so it can be detected. The data used in this extension is similar to, but not the same as, the data used in the tls-unique and/or tls-unique-for-telnet channel bindings described in [TLS-CHANNEL-BINDINGS]. This extension isn't a general-purpose RFC 5056 [RFC5056] channel binding facility, though πŸ’–

2. Conventions Used in This Document πŸ“–

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] πŸŽ€

3. Secure Renegotiation Definition 🌈

3.1. Additional Connection State

Both the client and the server need to store three extra values for each TLS connection state (see RFC 5246, Section 6.1) 🧚 These values belong to the connection itself, not to a TLS session cache entry, so keep that in mind!

  • a secure_renegotiation flag, indicating whether secure renegotiation is in use for this connection.
  • client_verify_data: the verify_data from the Finished message sent by the client on the immediately previous handshake. For currently defined TLS versions and cipher suites, this will be a 12-byte value. For SSLv3, it will be a 36-byte value.
  • server_verify_data: the verify_data from the Finished message sent by the server on the immediately previous handshake.

3.2. Extension Definition

This document defines a new TLS extension called renegotiation_info (extension type 0xff01). It holds a cryptographic binding to the enclosing TLS connection, if there is one, that the renegotiation is happening over ✨ The "extension data" field of this extension contains a RenegotiationInfo structure:

      struct {
          opaque renegotiated_connection<0..255>;
      } RenegotiationInfo;

Here's how the contents of this extension work πŸ’•

  • If this is the initial handshake for a connection, the renegotiated_connection field has zero length in both the ClientHello and the ServerHello. So the whole encoding of the extension is ff 01 00 01 00. The first two octets are the extension type, the third and fourth octets are the length of the extension itself, and the final octet is the zero length byte for the renegotiated_connection field.
  • For ClientHellos that are renegotiating, this field contains the client_verify_data specified in Section 3.1.
  • For ServerHellos that are renegotiating, this field contains the concatenation of client_verify_data and server_verify_data. For current versions of TLS, this will be a 24-byte value. For SSLv3, it will be a 72-byte value.

This extension can also be used with Datagram TLS (DTLS) [RFC4347] 🌊 For editorial simplicity this document just says TLS, but all of the requirements in this document apply equally to DTLS, so no cap, DTLS gets the same treatment 🫢

3.3. Renegotiation Protection Request Signaling Cipher Suite Value

okay so SSLv3 and TLS 1.0/TLS 1.1 both say implementations are supposed to ignore anything after the ClientHello (aka extensions) if they don't understand it πŸ™„ but some SSLv3 and TLS 1.0 implementations just... fail the whole handshake anyway πŸ’€ so clients that offer the renegotiation_info extension can run into handshake failures. to make things smoother with those servers, this doc defines a second signaling route: a special SCSV called TLS_EMPTY_RENEGOTIATION_INFO_SCSV with code point {0x00, 0xFF} πŸ¦‹

this SCSV is not a true cipher suite (it doesn't match any valid set of algorithms) and it can't be negotiated πŸ™…β€β™€οΈ instead it has the same semantics as an empty renegotiation_info extension, as the following sections explain. because SSLv3 and TLS implementations reliably ignore unknown cipher suites, the SCSV may be safely sent to any server ✨ it can also be included in the SSLv2 backward compatible CLIENT-HELLO (see Appendix E.2 of [RFC5246]) 🌸

Note: a minimal client that doesn't support renegotiation at all can just use the SCSV in all initial handshakes 🧚 the rules in the following sections will make any compliant server abort the handshake when it sees an apparent renegotiation attempt from that client πŸ”₯

3.4. Client Behavior: Initial Handshake

Note that this section and Section 3.5 apply to both full handshakes and session resumption handshakes πŸ’–

  • The client MUST include either an empty renegotiation_info extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the ClientHello. Including both is NOT RECOMMENDED πŸ™ˆ
  • When a ServerHello is received, the client MUST check if it includes the renegotiation_info extension:
    • If the extension is not present, the server does not support secure renegotiation; set secure_renegotiation flag to FALSE. In this case, some clients may want to terminate the handshake instead of continuing; see Section 4.1 for discussion.
    • If the extension is present, set the secure_renegotiation flag to TRUE. The client MUST then verify that the length of the renegotiated_connection field is zero, and if it is not, MUST abort the handshake (by sending a fatal handshake_failure alert).

Note: later in Section 3, "abort the handshake" is used as shorthand for "send a fatal handshake_failure alert and terminate the connection" ⭐

  • When the handshake has completed, the client needs to save the client_verify_data and server_verify_data values for future use πŸŽ€

3.5. Client Behavior: Secure Renegotiation

This text applies if the connection's "secure_renegotiation" flag is set to TRUE (if it is set to FALSE, see Section 4.2) 🌈

  • The client MUST include the renegotiation_info extension in the ClientHello, containing the saved client_verify_data. The SCSV MUST NOT be included. 🚫
  • When a ServerHello is received, the client MUST verify that the renegotiation_info extension is present; if it is not, the client MUST abort the handshake.
  • The client MUST then verify that the first half of the renegotiated_connection field is equal to the saved client_verify_data value, and the second half is equal to the saved server_verify_data value. If they are not, the client MUST abort the handshake. 😀
  • When the handshake has completed, the client needs to save the new client_verify_data and server_verify_data values. πŸ’œ

3.6. Server Behavior: Initial Handshake

Note that this section and Section 3.7 apply to both full handshakes and session-resumption handshakes 🌸

  • When a ClientHello is received, the server MUST check if it includes the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag to TRUE.
  • The server MUST check if the renegotiation_info extension is included in the ClientHello. If the extension is present, set secure_renegotiation flag to TRUE. The server MUST then verify that the length of the renegotiated_connection field is zero, and if it is not, MUST abort the handshake.
  • If neither the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV nor the renegotiation_info extension was included, set the secure_renegotiation flag to FALSE. In this case, some servers may want to terminate the handshake instead of continuing; see Section 4.3 for discussion. πŸ€”
  • If the secure_renegotiation flag is set to TRUE, the server MUST include an empty renegotiation_info extension in the ServerHello message. πŸ“
  • When the handshake has completed, the server needs to save the client_verify_data and server_verify_data values for future use. πŸ¦‹

TLS servers implementing this specification MUST ignore any unknown extensions offered by the client, and they MUST accept version numbers higher than their highest version number and negotiate the highest common version. These two requirements repeat requirements that already exist in RFC 5246, and they're only stated here for forward compatibility πŸ§šβ€β™€οΈ

Note that sending a renegotiation_info extension in response to a ClientHello containing only the SCSV is an explicit exception to the prohibition in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions. It's only allowed because the client is signaling that it's willing to receive the extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV πŸ‘‘ TLS implementations MUST continue to comply with Section 7.4.1.4 for all other extensions. πŸ’…

3.7. Server Behavior: Secure Renegotiation

This text applies if the connection's "secure_renegotiation" flag is set to TRUE (if it is set to FALSE, see Section 4.4) ✨

  • When a ClientHello is received, the server MUST verify that it does not contain the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If the SCSV is present, the server MUST abort the handshake. 🚨
  • The server MUST verify that the renegotiation_info extension is present; if it is not, the server MUST abort the handshake.
  • The server MUST verify that the value of the renegotiated_connection field is equal to the saved client_verify_data value; if it is not, the server MUST abort the handshake.
  • The server MUST include a renegotiation_info extension containing the saved client_verify_data and server_verify_data in the ServerHello. 🫢
  • When the handshake has completed, the server needs to save the new client_verify_data and server_verify_data values. 🌈

4. Backward Compatibility

Existing implementations that don't support this extension are widely deployed, and they generally have to interoperate with newer implementations that do support it πŸ₯Ί this section covers considerations for backward compatible interoperation πŸŽ€

4.1. Client Considerations

If a client offers the renegotiation_info extension or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV, and the server doesn't reply with renegotiation_info in the ServerHello, then that means the server doesn't support secure renegotiation 😬 some attacks (see Section 1) look like a single handshake to the client, so the client can't tell whether or not the connection is under attack. 😱 but heads up: just because the server doesn't acknowledge the extension doesn't mean it's vulnerable. it might choose to reject all renegotiations and simply not signal it. the catch is that the client can't figure out purely via TLS mechanisms whether or not that's the case πŸ€·β€β™€οΈ

if clients want to make sure these attacks are impossible, they need to terminate the connection immediately upon failing to receive the extension, without completing the handshake. such clients MUST generate a fatal "handshake_failure" alert prior to terminating the connection. however, it's expected that many TLS servers that don't support renegotiation (and so aren't vulnerable) won't support this extension either, so clients that do this will generally run into interoperability problems πŸ’€ there's no set of client behaviors that guarantees security and also achieves maximum interoperability during the transition period. clients need to pick one or the other when dealing with potentially un-upgraded servers βš–οΈ

4.2. Client Behavior: Legacy (Insecure) Renegotiation

This text applies if the connection's "secure_renegotiation" flag is set to FALSE. 🫣

it's possible that un-upgraded servers will request that the client renegotiate. it is RECOMMENDED that clients refuse this renegotiation request. clients that do so MUST respond to such requests with a "no_renegotiation" alert (RFC 5246 requires this alert to be at the "warning" level). πŸ™…β€β™€οΈ it's also possible that the apparently un-upgraded server is actually an attacker, who is then letting the client renegotiate with a different, legitimate, upgraded server πŸ‘€ if clients still choose to renegotiate, they MUST behave as described below.

clients that choose to renegotiate MUST provide either the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV or renegotiation_info in their ClientHello. in a legitimate renegotiation with an un-upgraded server, that server should ignore both of these signals. however, if the server (incorrectly) fails to ignore extensions, sending the renegotiation_info extension may cause a handshake failure. so it's permitted, though NOT RECOMMENDED, for the client to simply send the SCSV. this is the only situation in which clients are permitted to leave out the renegotiation_info extension in a ClientHello that's used for renegotiation 🧐

note that in the case of a downgrade attack, if this is an initial handshake from the server's perspective, then the client's use of the SCSV stops the server from detecting the attack (if this is a renegotiation from the server's perspective, then it will detect the attack). however, the client will detect the attack when the server sends an empty renegotiation_info extension and the client is expecting one containing the previous verify_data. by contrast, if the client sends the renegotiation_info extension, then the server will detect the attack immediately ⚑

when the ServerHello is received, the client MUST verify that it does not contain the renegotiation_info extension. if it does, the client MUST abort the handshake. (because the server has already indicated that it doesn't support secure renegotiation, the only way this can happen is if the server is broken or there's an attack 🚩)

4.3. Server Considerations ✨

okay so if the client doesn't offer the renegotiation_info extension or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV, that means it does not support secure renegotiation πŸ™ˆ. The attack from Section 1 looks like two handshakes to the server, but other attacks might be possible where the renegotiation is only seen by the client 😬. So if servers want to be sure those attacks are impossible, they need to terminate the connection immediately when secure renegotiation isn't negotiated. Servers that do choose to let unpatched clients connect can still block the attack from Section 1 by refusing to renegotiate over those connections πŸ’….

so clients can probe, even servers that don't support renegotiation MUST implement the minimal version of the extension from this document for initial handshakes. that way they signal that they've been upgraded πŸ†™πŸ¦‹

4.4. Server Behavior: Legacy (Insecure) Renegotiation

this part applies if the connection's secure_renegotiation flag is set to FALSE πŸŽ€

it is RECOMMENDED that servers not permit legacy renegotiation πŸ™…β€β™€οΈ. if servers still decide to allow it, they MUST follow the requirements in this section πŸ’œ

  • when a ClientHello is received, the server MUST verify that it does not contain the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. if the SCSV is present, the server MUST abort the handshake 🚫
  • the server MUST verify that the renegotiation_info extension is not present; if it is, the server MUST abort the handshake 🚫

4.5. SSLv3

okay bestie, SSLv3 is not a protocol under IETF change control (see [SSLv3]) πŸ™ƒ, but it was the original basis for TLS and most TLS implementations still support it. so the IETF encourages SSLv3 implementations to adopt the renegotiation_info extension and SCSV from this document 🌸. the semantics of the SCSV and the extension are identical to TLS stacks, except for the size of the verify_data values, which are 36 bytes long each πŸ”’. heads up: this will require adding at least minimal extension processing to those stacks ⚠️.

clients that support SSLv3 and offer secure renegotiation (either via SCSV or renegotiation_info) MUST accept the renegotiation_info extension from the server, even if the server version is {0x03, 0x00}, and behave as described in this specification. πŸ’… and TLS servers that support secure renegotiation AND SSLv3 MUST accept the SCSV or the renegotiation_info extension and respond as described in this specification, even if the offered client version is {0x03, 0x00} 🫢.

SSLv3 doesn't define the no_renegotiation alert, and it doesn't have a way to say "no thanks, I won't renegotiate" at a "warning" level 😭. so SSLv3 clients that refuse renegotiation SHOULD use a fatal handshake_failure alert πŸ’€.


5. Security Considerations πŸ”₯

this is the serious part, so pay attention πŸ‘€. the extension in this document prevents an attack on TLS. if the extension isn't used, TLS renegotiation is vulnerable to an attack where the attacker injects their own conversation with the TLS server as a prefix to the client's conversation 😱. the scary bit is that it's invisible to the client, and to the server it looks like an ordinary renegotiation πŸ™ˆ. the extension defined here lets renegotiation happen safely ✨. servers SHOULD NOT allow clients to renegotiate without using this extension 🚫. and honestly? lots of servers can stop this attack just by refusing to renegotiate at all πŸ™…β€β™€οΈ.

while this extension fixes the man-in-the-middle attack from the overview, it does NOT solve every problem an application can hit if it doesn't know about renegotiation 🧐. for example, during renegotiation, either the client or the server can present a different certificate than was used earlier πŸ“œ. that can totally surprise app developers (who might expect that a getPeerCertificates() API call returns the same value when called twice 🀯), and it might get handled in an insecure way πŸ’”.

TLS implementations SHOULD provide a mechanism to disable and enable renegotiation πŸ”˜.

TLS implementers are encouraged to clearly document how renegotiation interacts with the APIs they offer to applications πŸ“. for example: which API calls might return different values on different calls, or which callbacks might get called multiple times πŸ”.

to make life easier for applications that use renegotiation but don't expect the certificate to change once it's been authenticated πŸ₯Ί, TLS implementations may also want to offer applications the option to abort renegotiation if the peer tries to authenticate with a different certificate and/or a different server name (in the server_name extension) than was used earlier πŸ›‘. TLS implementations may alternatively offer the option to disable renegotiation once the client certificate has been authenticated πŸ”’. BUT: turning these options on by default for every app could break existing apps that depend on renegotiation to switch from one certificate to another πŸ’₯. (for example, long-lived TLS connections could move over to a renewed certificate, or renegotiation could select a different cipher suite that needs a different certificate πŸ”„.)

last thing, designers of apps that depend on renegotiation: many TLS APIs represent application data as a simple octet stream 🌊. apps may not be able to tell exactly which application data octets were received before, during, or after renegotiation πŸ€·β€β™€οΈ. especially if the peer presents a different certificate during renegotiation, you need to be careful about how the app handles that data ⚠️🫢.


6. IANA Considerations 🧚

IANA has added the extension code point 65281 (0xff01) for the renegotiation_info extension to the TLS ExtensionType values registry 🌈. this code point was already being used for prototype implementations πŸ› οΈ.

IANA has also added TLS cipher suite number 0x00,0xFF with the name TLS_EMPTY_RENEGOTIATION_INFO_SCSV to the TLS Cipher Suite registry πŸ“.

7. Acknowledgements πŸ’œ

this vulnerability was originally discovered by Marsh Ray and independently rediscovered by Martin Rex πŸ•΅οΈβ€β™€οΈ. the general concept behind the extension in this document was independently invented by Steve Dispensa, Nasko Oskov, and Eric Rescorla πŸ‘‘, with refinements from Nelson Bolyard, Pasi Eronen, Michael D'Errico, Stephen Farrell, Michael Gray, David-Sarah Hopwood, Ben Laurie, David Makepeace, Bodo Moeller, Martin Rex, Peter Robinson, Jesse Walker, Nico Williams, and other members of the Project Mogul team and the TLS WG 🌟. absolute legends, all of them 🫢✨.

8. References πŸ“š

8.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC5246]  Dierks, T. and E. Rescorla, "The Transport Layer Security
           (TLS) Protocol Version 1.2", RFC 5246, August 2008.

8.2. Informative References

[RFC4347]  Rescorla, E. and N. Modadugu, "Datagram Transport Layer
           Security", RFC 4347, April 2006.

[RFC5056]  Williams, N., "On the Use of Channel Bindings to Secure
           Channels", RFC 5056, November 2007.

[TLS-CHANNEL-BINDINGS]
           Altman, J., Williams, N., and L. Zhu, "Channel Bindings
           for TLS", Work in Progress, October 2009.

[RFC2818]  Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.

[RFC2965]  Kristol, D. and L. Montulli, "HTTP State Management
           Mechanism", RFC 2965, October 2000.

[Ray09]    Ray, M., "Authentication Gap in TLS Renegotiation",
           November 2009, <http://extendedsubset.com/?p=8>.

[SSLv3]    Freier, A., Karlton, P., and P. Kocher, "The SSL Protocol
           Version 3.0", Work in Progress, November 1996.

Authors' Addresses πŸ¦‹

Eric Rescorla
RTFM, Inc.
2064 Edgewood Drive
Palo Alto, CA  94303
USA

EMail:  ekr@rtfm.com


Marsh Ray
PhoneFactor
7301 W 129th Street
Overland Park, KS  66213
USA

EMail:  marsh@extendedsubset.com


Steve Dispensa
PhoneFactor
7301 W 129th Street
Overland Park, KS  66213
USA

EMail:  dispensa@phonefactor.com


Nasko Oskov
Microsoft
One Microsoft Way
Redmond, WA  98052
USA

EMail:  nasko.oskov@microsoft.com
πŸ“¦ where this page comes from