idnits 2.17.1 draft-ietf-cat-kerberos-pk-init-02.txt: ** The Abstract section seems to be numbered Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Cannot find the required boilerplate sections (Copyright, IPR, etc.) in this document. Expected boilerplate is as follows today (2024-04-27) according to https://trustee.ietf.org/license-info : IETF Trust Legal Provisions of 28-dec-2009, Section 6.a: This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. IETF Trust Legal Provisions of 28-dec-2009, Section 6.b(i), paragraph 2: Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved. IETF Trust Legal Provisions of 28-dec-2009, Section 6.b(i), paragraph 3: This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing expiration date. The document expiration date should appear on the first and last page. ** The document seems to lack a 1id_guidelines paragraph about Internet-Drafts being working documents. ** The document seems to lack a 1id_guidelines paragraph about 6 months document validity -- however, there's a paragraph with a matching beginning. Boilerplate error? ** The document seems to lack a 1id_guidelines paragraph about the list of current Internet-Drafts. ** The document seems to lack a 1id_guidelines paragraph about the list of Shadow Directories. ** The document is more than 15 pages and seems to lack a Table of Contents. == No 'Intended status' indicated for this document; assuming Proposed Standard == The page length should not exceed 58 lines per page, but there was 10 longer pages, the longest (page 9) being 60 lines Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an Introduction section. ** The document seems to lack a Security Considerations section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** There are 3 instances of too long lines in the document, the longest one being 1 character in excess of 72. ** There are 12 instances of lines with control characters in the document. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 227: '...e changes in this section is REQUIRED....' RFC 2119 keyword, line 330: '... cksum[0] Checksum OPTIONAL,...' RFC 2119 keyword, line 336: '... clientPubValue[6] SubjectPublicKeyInfo OPTIONAL,...' RFC 2119 keyword, line 338: '... recoveryData[7] RecoveryData OPTIONAL...' RFC 2119 keyword, line 344: '... kdcPubValueId[1] INTEGER OPTIONAL...' (15 more instances...) == The 'Updates: ' line in the draft header should list only the _numbers_ of the RFCs which will be updated by this document (if approved); it should not include the word 'RFC' in the list. -- The draft header indicates that this document updates RFC1510, but the abstract doesn't seem to directly say this. It does mention RFC1510 though, so this could be OK. Miscellaneous warnings: ---------------------------------------------------------------------------- == Line 13 has weird spacing: '...-Drafts are ...' == Line 19 has weird spacing: '... months and ...' == Line 20 has weird spacing: '...-Drafts as...' == Line 21 has weird spacing: '...ference mater...' == Line 30 has weird spacing: '...tion of this ...' (Using the creation date from RFC1510, updated by this document, for RFC5378 checks: 1993-09-01) -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- Couldn't find a document date in the document -- date freshness check skipped. -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Missing reference section? '0' on line 1000 looks like a reference -- Missing reference section? '1' on line 1001 looks like a reference -- Missing reference section? '2' on line 996 looks like a reference -- Missing reference section? '3' on line 627 looks like a reference -- Missing reference section? '4' on line 628 looks like a reference -- Missing reference section? '5' on line 629 looks like a reference -- Missing reference section? '6' on line 630 looks like a reference -- Missing reference section? '7' on line 631 looks like a reference -- Missing reference section? '8' on line 632 looks like a reference -- Missing reference section? '9' on line 633 looks like a reference -- Missing reference section? '10' on line 634 looks like a reference -- Missing reference section? 'Jaspan' on line 777 looks like a reference Summary: 14 errors (**), 0 flaws (~~), 8 warnings (==), 16 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 INTERNET-DRAFT Clifford Neuman 2 draft-ietf-cat-kerberos-pk-init-02.txt Brian Tung 3 Updates: RFC 1510 ISI 4 expires April 19, 1997 John Wray 5 Digital Equipment Corporation 6 Jonathan Trostle 7 CyberSafe Corporation 9 Public Key Cryptography for Initial Authentication in Kerberos 11 0. Status Of this Memo 13 This document is an Internet-Draft. Internet-Drafts are working 14 documents of the Internet Engineering Task Force (IETF), its areas, 15 and its working groups. Note that other groups may also distribute 16 working documents as Internet-Drafts. 18 Internet-Drafts are draft documents valid for a maximum of six 19 months and may be updated, replaced, or obsoleted by other docu- 20 ments at any time. It is inappropriate to use Internet-Drafts as 21 reference material or to cite them other than as ``work in pro- 22 gress.'' 24 To learn the current status of any Internet-Draft, please check the 25 ``1id-abstracts.txt'' listing contained in the Internet-Drafts Sha- 26 dow Directories on ds.internic.net (US East Coast), nic.nordu.net 27 (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific 28 Rim). 30 The distribution of this memo is unlimited. It is filed as 31 draft-ietf-cat-kerberos-pk-init-02.txt, and expires April 19, 1997. 32 Please send comments to the authors. 34 1. Abstract 36 This document defines extensions to the Kerberos protocol 37 specification (RFC 1510, "The Kerberos Network Authentication 38 Service (V5)", September 1993) to provide a method for using public 39 key cryptography during initial authentication. The method defined 40 specifies the way in which preauthentication data fields and error 41 data fields in Kerberos messages are to be used to transport public 42 key data. 44 2. Motivation 46 Public key cryptography presents a means by which a principal may 47 demonstrate possession of a key, without ever having divulged this 48 key to anyone else. In conventional cryptography, the encryption 49 key and decryption key are either identical or can easily be 50 derived from one another. In public key cryptography, however, 51 neither the public key nor the private key can be derived from the 52 other (although the private key RECORD may include the information 53 required to generate BOTH keys). Hence, a message encrypted with a 54 public key is private, since only the person possessing the private 55 key can decrypt it; similarly, someone possessing the private key 56 can also encrypt a message, thus providing a digital signature. 58 Furthermore, conventional keys are often derived from passwords, so 59 messages encrypted with these keys are susceptible to dictionary 60 attacks, whereas public key pairs are generated from a 61 pseudo-random number sequence. While it is true that messages 62 encrypted using public key cryptography are actually encrypted with 63 a conventional secret key, which is in turn encrypted using the 64 public key pair, the secret key is also randomly generated and is 65 hence not vulnerable to a dictionary attack. 67 The advantages provided by public key cryptography have produced a 68 demand for its integration into the Kerberos authentication 69 protocol. The public key integration into Kerberos described in 70 this document has three goals. 72 First, by allowing users to register public keys with the KDC, the 73 KDC can be recovered much more easily in the event it is 74 compromised. With Kerberos as it currently stands, compromise of 75 the KDC is disastrous. All keys become known by the attacker and 76 all keys must be changed. Second, we allow users that have public 77 key certificates signed by outside authorities to obtain Kerberos 78 credentials for access to Kerberized services. Third, we obtain the 79 above benefits while maintaining the performance advantages of 80 Kerberos over protocols that use only public key authentication. 82 If users register public keys, compromise of the KDC does not 83 divulge their private key. Compromise of security on the KDC is 84 still a problem, since an attacker can impersonate any user by 85 creating a ticket granting ticket for the user. When the compromise 86 is detected, the KDC can be cleaned up and restored from backup 87 media and loaded with a backup private/public key pair. Keys for 88 application servers are conventional symmetric keys and must be 89 changed. 91 Note: If a user stores his private key, in an encrypted form, on 92 the KDC, then it may be desirable to change the key pair, since the 93 private key is encrypted using a symmetric key derived from a 94 password (as described below), and can therefore be vulnerable to 95 dictionary attack if a good password policy is not used. 96 Alternatively, if the encrypting symmetric key has 56 bits, then it 97 may also be desirable to change the key pair after a short period 98 due to the short key length. The KDC does not have access to the 99 user's unencrypted private key. 101 There are two important areas where public key cryptography will 102 have immediate use: in the initial authentication of users 103 registered with the KDC or using public key certificates from 104 outside authorities, and to establish inter-realm keys for 105 cross-realm authentication. This memo describes a method by which 106 the first of these can be done. The second case will be the topic 107 for a separate proposal. 109 Some of the ideas on which this proposal is based arose during 110 discussions over several years between members of the SAAG, the 111 IETF-CAT working group, and the PSRG, regarding integration of 112 Kerberos and SPX. Some ideas are drawn from the DASS system, and 113 similar extensions have been discussed for use in DCE. These 114 changes are by no means endorsed by these groups. This is an 115 attempt to revive some of the goals of that group, and the 116 proposal approaches those goals primarily from the Kerberos 117 perspective. 119 3. Initial authentication of users with public keys 121 This section describes the extensions to Version 5 of the Kerberos 122 protocol that will support the use of public key cryptography by 123 users in the initial request for a ticket granting ticket. 125 Roughly speaking, the following changes to RFC 1510 are proposed: 126 Users can initially authenticate using public key or conventional 127 (symmetric key) cryptography. After a KDC compromise, the KDC 128 replies with an error message that informs the client of the new 129 KDC public backup key. Users must authenticate using public key 130 cryptography in response to the error message. If applicable, the 131 client generates the new user secret key at this point as well. 133 Public key initial authentication is performed using either the 134 RSA encryption or Diffie Hellman public key algorithms. There is 135 also an option to allow the user to store his/her private key 136 encrypted in the user password in the KDC database; this option 137 solves the problem of transporting the user private key to 138 different workstations. The combination of this option and the 139 provision for conventional symmetric key authentication allows 140 organizations to smoothly migrate to public key cryptography. 142 This proposal will allow users either to use keys registered 143 directly with the KDC, or to use keys already registered for use 144 with X.509, PEM, or PGP, to obtain Kerberos credentials. These 145 credentials can then be used, as before, with application servers 146 supporting Kerberos. Use of public key cryptography will not be a 147 requirement for Kerberos, but if one's organization runs a KDC 148 supporting public key, then users may choose to be registered with 149 a public key pair, instead of or in addition to the current secret 150 key. 152 The application request and response between Kerberos clients and 153 application servers will continue to be based on conventional 154 cryptography, or will be converted to use user-to-user 155 authentication. There are performance issues and other reasons 156 that servers may be better off using conventional cryptography. 157 For this proposal, we feel that 80 percent of the benefits of 158 integrating public key with Kerberos can be attained for 20 percent 159 of the effort, by addressing only initial authentication. This 160 proposal does not preclude separate extensions. 162 With these changes, users will be able to register public keys, 163 only in realms that support public key, but they will still be able 164 to perform initial authentication from a client that does not 165 support public key. They will be able to use services registered in 166 any realm. Furthermore, users registered with conventional keys 167 will be able to use any client. 169 This proposal addresses three ways in which users may use public 170 key cryptography for initial authentication with Kerberos, with 171 minimal change to the existing protocol. Users may register keys 172 directly with the KDC, or they may present certificates by outside 173 certification authorities (or certifications by other users) 174 attesting to the association of the public key with the named user. 175 In both cases, the end result is that the user obtains a 176 conventional ticket granting ticket or conventional server ticket 177 that may be used for subsequent authentication, with such 178 subsequent authentication using only conventional cryptography. 180 Additionally, users may also register a digital signature 181 verification key with the KDC. We provide this option for the 182 licensing benefits, as well as a simpler variant of the initial 183 authentication exchange. However, this option relies on the client 184 to generate random keys. 186 We first consider the case where the user's key is registered with 187 the KDC. 189 3.1 Definitions 191 Before we proceed, we will lay some groundwork definitions for 192 encryption and signatures. We propose the following definitions 193 of signature and encryption modes (and their corresponding values 194 on the wire): 196 #define ENCTYPE_SIGN_MD5_RSA 0x0011 198 #define ENCTYPE_ENCRYPT_RSA_PRIV 0x0021 199 #define ENCTYPE_ENCRYPT_RSA_PUB 0x0022 201 allowing further modes to be defined accordingly. 203 In the exposition below, we will use the notation E (T, K) to 204 denote the encryption of data T, with key (or parameters) K. 206 If E is ENCTYPE_SIGN_MD5_RSA, then 208 E (T, K) = {T, RSAEncryptPrivate (MD5Hash (T), K)} 210 If E is ENCTYPE_ENCRYPT_RSA_PRIV, then 212 E (T, K) = RSAEncryptPrivate (T, K) 214 Correspondingly, if E is ENCTYPE_ENCRYPT_RSA_PUB, then 216 E (T, K) = RSAEncryptPublic (T, K) 218 3.2 Initial request for user registered with public key on KDC 220 In this scenario it is assumed that the user is registered with a 221 public key on the KDC. The user's private key may be held by the 222 user, or it may be stored on the KDC, encrypted so that it cannot 223 be used by the KDC. 225 3.2.1 User's private key is stored locally 227 Implementation of the changes in this section is REQUIRED. 229 In this section, we present the basic Kerberos V5 pk-init protocol 230 that all conforming implementations must support. The key features 231 of the protocol are: (1) easy, automatic (for the clients) recovery 232 after a KDC compromise, (2) the ability for a realm to support a 233 mix of old and new Kerberos V5 clients with the new clients being a 234 mix of both public key and symmetric key configured clients, and 235 (3) support for Diffie-Hellman (DH) key exchange as well as RSA 236 public key encryption. The benefit of having new clients being able 237 to use either symmetric key or public key initial authentication is 238 that it allows an organization to roll out the new clients as 239 rapidly as possible without having to be concerned about the need 240 to purchase additional hardware to support the CPU intensive public 241 key cryptographic operations. 243 In order to give a brief overview of the four protocols in this 244 section, we now give diagrams of the protocols. We denote 245 encryption of message M with key K by {M}K and the signature of 246 message M with key K by [M]K. All messages from the KDC to the 247 client are AS_REP messages unless denoted otherwise; similarly, all 248 messages from the client to the KDC are AS_REQ messages unless 249 denoted otherwise. Since only the padata fields are affected by 250 this specification in the AS_REQ and AS_REP messages, we do not 251 show the other fields. We first show the RSA encryption option in 252 normal mode: 254 certifier list, [cksum, time, nonce, kdcRealm, 255 kdcName]User PrivateKey 256 C ------------------------------------------------------> KDC 258 list of cert's, {[encReplyKey, nonce]KDC privkey} 259 EncReplyTmpKey, {EncReplyTmpKey}Userpubkey 260 C <------------------------------------------------------ KDC 262 We now show RSA encryption in recovery mode: 264 certifier list, [cksum, time, nonce, kdcRealm, 265 kdcName]User PrivateKey 266 C ------------------------------------------------------> KDC 268 KRB_ERROR (error code KDC_RECOVERY_NEEDED) 269 error data: [nonce, algID (RSA), 270 KDC PublicKey Kvno and PublicKey, KDC Salt] 271 Signed with KDC PrivateKey 272 C <------------------------------------------------------ KDC 274 certifier list, [cksum, time, nonce, kdcRealm, kdcName, 275 {newUserSymmKey, nonce}KDC public key]User PrivateKey 276 C ------------------------------------------------------> KDC 278 list of cert's, {[encReplyKey, nonce]KDC privkey} 279 EncReplyTmpKey, {EncReplyTmpKey}Userpubkey 280 C <------------------------------------------------------ KDC 281 Next, we show Diffie Hellman in normal mode: 283 certifier list, [cksum, time, nonce, kdcRealm, kdcName, 284 User DH public parameter]User PrivateKey 285 C ------------------------------------------------------> KDC 287 list of cert's, {encReplyKey, nonce}DH shared symmetric 288 key, [KDC DH public parameter]KDC Private Key 289 C <------------------------------------------------------ KDC 291 Finally, we show Diffie Hellman in recovery mode: 293 certifier list, [cksum, time, nonce, kdcRealm, kdcName, 294 User DH public parameter]User PrivateKey 295 C ------------------------------------------------------> KDC 297 KRB_ERROR (error code KDC_RECOVERY_NEEDED) 298 error data: [nonce, algID (DH), KDC DH public 299 parameter, KDC DH ID, KDC PublicKey 300 Kvno and PublicKey, KDC Salt] 301 Signed with KDC PrivateKey 302 C <------------------------------------------------------ KDC 304 certifier list, [cksum, time, nonce, kdcRealm, 305 kdcName, User DH public parameter, {newUserSymmKey, 306 nonce}DH shared key, KDC DH ID]User PrivateKey 307 C ------------------------------------------------------> KDC 309 list of cert's, {encReplyKey, nonce}DH shared 310 symmetric key 311 C <------------------------------------------------------ KDC 313 If the user stores his private key locally, the initial request 314 to the KDC for a ticket granting ticket proceeds according to 315 RFC 1510, except that a preauthentication field containing a 316 nonce signed by the user's private key is included. The 317 preauthentication field may also include a list of the root 318 certifiers trusted by the user. 320 PA-PK-AS-ROOT ::= SEQUENCE { 321 rootCert[0] SEQUENCE OF OCTET STRING, 322 signedAuth[1] SignedPKAuthenticator 323 } 325 SignedPKAuthenticator ::= SEQUENCE { 326 authent[0] PKAuthenticator, 327 authentSig[1] Signature 328 } 329 PKAuthenticator ::= SEQUENCE { 330 cksum[0] Checksum OPTIONAL, 331 cusec[1] INTEGER, 332 ctime[2] KerberosTime, 333 nonce[3] INTEGER, 334 kdcRealm[4] Realm, 335 kdcName[5] PrincipalName, 336 clientPubValue[6] SubjectPublicKeyInfo OPTIONAL, 337 -- DH algorithm 338 recoveryData[7] RecoveryData OPTIONAL 339 -- Recovery Alg. 340 } 342 RecoveryData ::= SEQUENCE { 343 clientRecovData[0] ClientRecovData, 344 kdcPubValueId[1] INTEGER OPTIONAL 345 -- DH algorithm, copied 346 -- from KDC response 347 } 349 ClientRecovData ::= CHOICE { 350 newPrincKey[0] EncryptedData, -- EncPaPkAsRoot 351 -- encrypted with 352 -- either KDC 353 -- public key or 354 -- DH shared key 355 recovDoneFlag[1] INTEGER -- let KDC know that 356 -- recovery is done 357 -- when user uses a 358 -- mix of clients or 359 -- does not want to 360 -- keep a symmetric 361 -- key in the database 362 } 364 EncPaPkAsRoot ::= SEQUENCE { 365 newSymmKey[0] EncryptionKey -- the principal's new 366 -- symmetric key 367 nonce[1] INTEGER -- the same nonce as 368 -- the one in the 369 -- PKAuthenticator 370 } 372 Signature ::= SEQUENCE { 373 sigType[0] INTEGER, 374 kvno[1] INTEGER OPTIONAL, 375 sigHash[2] OCTET STRING 376 } 378 Notationally, sigHash is then 380 sigType (authent, userPrivateKey) 382 where userPrivateKey is the user's private key (corresponding to the 383 public key held in the user's database record). Valid sigTypes are 384 thus far limited to the above-listed ENCTYPE_SIGN_MD5_RSA; we expect 385 that other types may be listed (and given on-the-wire values between 386 0x0011 and 0x001f). 388 The format of each certificate depends on the particular service 389 used. (Alternatively, the KDC could send, with its reply, a 390 sequence of certifications (see below), but since the KDC is likely 391 to have more certifications than users have trusted root certifiers, 392 we have chosen the first method.) In the event that the client 393 believes it already possesses the current public key of the KDC, a 394 zero-length root-cert field is sent. 396 The fields in the signed authenticator are the same as those in the 397 Kerberos authenticator; in addition, we include a client-generated 398 nonce, and the name of the KDC. The structure is itself signed 399 using the user's private key corresponding to the public key 400 registered with the KDC. We include the newSymmKey field so clients 401 can generate a new symmetric key (for users, this key is based on 402 a password and a salt value generated by the KDC) and 403 confidentially send this key to the KDC during the recovery phase. 405 We now describe the recovery phase of the protocol. There is a bit 406 associated with each principal in the database indicating whether 407 recovery for that principal is necessary. After a KDC compromise, 408 the KDC software is reloaded from backup media and a new backup 409 KDC public/private pair is generated. The public half of this pair 410 is then either made available to the KDC, or given to the 411 appropriate certification authorities for certification. The private 412 half is not made available to the KDC until after the next 413 compromise clean-up. If clients are maintaining a copy of the KDC 414 public key, they also have a copy of the backup public key. 416 After the reload of KDC software, the bits associated with 417 recovery of each principal are all set. The KDC clears the bit 418 for each principal that undergoes the recovery phase. In addition, 419 there is a bit associated with each principal to indicate whether 420 there is a valid symmetric key in the database for the principal. 421 These bits are all cleared after the reload of the KDC software 422 (the old symmetric keys are no longer valid). Finally, there is a 423 bit associated with each principal indicating whether that 424 principal still uses non-public key capable clients. If a user 425 principal falls into this category, a public key capable client 426 cannot transparently re-establish a symmetric key for that user, 427 since the older clients would not be able to compute the new 428 symmetric key that includes hashing the password with a KDC 429 supplied salt value. The re-establishment of the symmetric key 430 in this case is outside the scope of this protocol. 432 One method of re-establishing a symmetric key for public key 433 capable clients is to generate a hash of the user password and a 434 KDC supplied salt value. The KDC salt is changed after every 435 compromise of the KDC. In the recovery protocol, if the principal 436 does not still use old clients, the KDC supplied salt is sent to 437 the client principal in a KRB_ERROR message with error code 438 KDC_RECOVERY_NEEDED. The error data field of the message contains 439 the following structure which is encoded into an octet string. 441 PA-PK-KDC-ERR ::= CHOICE { 442 recoveryDhErr SignedDHError, -- Used during recovery 443 -- when algorithm is DH 444 -- based 445 recoveryPKEncErr SignedPKEncError -- Used during recovery 446 -- for PK encryption 447 -- (RSA,...) 448 } 450 SignedDHError ::= SEQUENCE { 451 dhErr DHError, 452 dhErrSig Signature 453 } 455 SignedPKEncError ::= SEQUENCE { 456 pkEncErr PKEncryptError, 457 pkEncErrSig Signature 458 } 460 DHError ::= SEQUENCE { 461 nonce INTEGER, -- From AS_REQ 462 algorithmId INTEGER, -- DH algorithm 463 kdcPubValue SubjectPublicKeyInfo, -- DH algorithm 464 kdcPubValueId INTEGER, -- DH algorithm 465 kdcPublicKeyKvno INTEGER OPTIONAL, -- New KDC public 466 -- key kvno 467 kdcPublicKey OCTET STRING OPTIONAL, -- New KDC pubkey 468 kdcSalt OCTET STRING OPTIONAL -- If user uses 469 -- only new 470 -- clients 471 } 473 PKEncryptError ::= SEQUENCE { 474 nonce INTEGER, -- From AS_REQ 475 algorithmId INTEGER, -- Public Key 476 -- encryption alg 477 kdcPublicKeyKvno INTEGER OPTIONAL, -- New KDC public 478 -- key kvno 479 kdcPublicKey OCTET STRING OPTIONAL, -- New KDC public 480 -- key 481 kdcSalt OCTET STRING OPTIONAL -- If user uses 482 -- only new 483 -- clients 484 } 486 The KDC_RECOVERY_NEEDED error message is sent in response to a 487 client AS_REQ message if the client principal needs to be 488 recovered, unless the client AS_REQ contains the PKAuthenticator 489 with a nonempty RecoveryData field (in this case the client has 490 already received the KDC_RECOVERY_NEEDED error message. We will 491 also see in section 3.2.2 that a different error response is 492 sent by the KDC if the encrypted user private key is stored in 493 the KDC database.) If the client principal uses only new clients, 494 then the kdcSalt field is returned; otherwise, the kdcSalt field 495 is absent. 497 If the client uses the Diffie Hellman algorithm during the recovery 498 phase then the DHError field contains the public Diffie Hellman 499 parameter (kdcPubValue) for the KDC along with an identifier 500 (kdcPubValueID). The client will then send this identifier to 501 the KDC in an AS_REQ message; the identifier allows the KDC to 502 look up the Diffie Hellman private value corresponding to the 503 identifier. Depending on how often the KDC updates its private 504 Diffie Hellman parameters, it will have to store anywhere between a 505 handful and several dozen of these identifiers and their parameters. 506 The KDC must send its Diffie Hellman public value to the client 507 first so the client can encrypt its new symmetric key. 509 In the case where the user principal does not need to be recovered 510 and the user still uses old clients as well as new clients, the 511 KDC_ERR_NULL_KEY error is sent in response to symmetric AS_REQ 512 messages when there is no valid symmetric key in the KDC database. 513 This situation can occur if the user principal has been recovered 514 but no new symmetric key has been established in the database. 516 In addition, the two error messages with error codes 517 KDC_ERR_PREAUTH_FAILED and KDC_ERR_PREAUTH_REQUIRED are modified 518 so the error data contains the kdcSalt encoded as an OCTET STRING. 519 The reason for the modification is to allow principals that use 520 new clients only to have their symmetric key transparently updated 521 by the client software during the recovery phase. The kdcSalt is 522 used to create the new symmetric key. As a performance optimization, 523 the kdcSalt is stored in the /krb5/salt file along with the realm. 524 Thus the /krb5/salt file consists of realm-salt pairs. If the file 525 is missing, or the salt is not correct, the above error messages 526 allow the client to find out the correct salt. New clients which 527 are configured for symmetric key authentication attempt to 528 preauthenticate with the salt from the /krb5/salt file as an 529 input into their key, and if the file is not present, the new client 530 does not use preauthentication. The error messages above return 531 either the correct salt to use, or no salt at all which indicates 532 that the principal is still using old clients (the client software 533 should use the existing mapping from the user password to the 534 symmetric key). 536 In order to assure interoperability between clients from different 537 vendors and organizations, a standard algorithm is needed for 538 creating the symmetric key from the principal password and kdcSalt. 539 The algorithm for creating the symmetric key is as follows: take the 540 SHA-1 hash of the kdcSalt concatenated with the principal password 541 and use the 20 byte output as the input into the existing key 542 generation process (string to key function). After a compromise, the 543 KDC changes the kdcSalt; thus, the recovery algorithm allows users 544 to obtain a new symmetric key without actually changing their 545 password. 547 The response from the KDC would be identical to the response in RFC 548 1510, except that instead of being encrypted in the secret key 549 shared by the client and the KDC, it is encrypted in a random key 550 freshly generated by the KDC (of type ENCTYPE_ENC_CBC_CRC). A 551 preauthentication field (specified below) accompanies the response, 552 optionally containing a certificate with the public key for the KDC 553 (since we do not assume that the client knows this public key), and 554 a package containing the secret key in which the rest of the 555 response is encrypted, along with the same nonce used in the rest 556 of the response, in order to prevent replays. This package is itself 557 signed with the private key of the KDC, then encrypted with the 558 symmetric key that is returned encrypted in the public key of the 559 user (or for Diffie Hellman, encrypted in the shared secret Diffie 560 Hellman symmetric key). 562 Pictorially, in the public key encryption case we have: 564 kdcCert, {[encReplyKey, nonce] Sig w/KDC 565 privkey}EncReplyTmpKey, {EncReplyTmpKey}Userpubkey 567 Pictorially, in the Diffie Hellman case we have: 569 kdcCert, {encReplyKey, nonce}DH shared symmetric key, 570 [DH public value]Sig w/KDC privkey 572 PA-PK-AS-REP ::= SEQUENCE { 573 kdcCert[0] SEQUENCE OF Certificate, 574 encryptShell[1] EncryptedData, 575 -- EncPaPkAsRepPartShell 576 -- encrypted by 577 -- encReplyTmpKey or DH 578 -- shared symmetric key 579 pubKeyExchange[2] PubKeyExchange OPTIONAL, 580 -- a choice between 581 -- a KDC signed DH 582 -- value and a public 583 -- key encrypted 584 -- symmetric key. 585 -- Not needed after 586 -- recovery when 587 -- DH is used. 588 } 590 PubKeyExchange ::= CHOICE { 591 signedDHPubVal SignedDHPublicValue, 592 encryptKey EncryptedData 593 -- EncPaPkAsRepTmpKey 594 -- encrypted by 595 -- userPublicKey 596 } 598 SignedDHPublicValue ::= SEQUENCE { 599 dhPublic[0] SubjectPublicKeyInfo, 600 dhPublicSig[1] Signature 601 } 603 EncPaPkAsRepPartShell ::= SEQUENCE { 604 encReplyPart[0] EncPaPkAsRepPart, 605 encReplyPartSig[1] Signature OPTIONAL 606 -- encReplyPart 607 -- signed by kdcPrivateKey 608 -- except not present in 609 -- DH case 610 } 611 EncPaPkAsRepPart ::= SEQUENCE { 612 encReplyKey[0] EncryptionKey, 613 nonce[1] INTEGER, 614 } 616 EncPaPkAsRepTmpKey ::= SEQUENCE { 617 encReplyTmpKey[0] EncryptionKey 618 } 620 The kdc-cert specification is lifted, with slight modifications, 621 from v3 of the X.509 certificate specification: 623 Certificate ::= SEQUENCE { 624 version[0] Version DEFAULT v1 (1), 625 serialNumber[1] CertificateSerialNumber, 626 signature[2] AlgorithmIdentifier, 627 issuer[3] PrincipalName, 628 validity[4] Validity, 629 subjectRealm[5] Realm, 630 subject[6] PrincipalName, 631 subjectPublicKeyInfo[7] SubjectPublicKeyInfo, 632 issuerUniqueID[8] IMPLICIT UniqueIdentifier OPTIONAL, 633 subjectUniqueID[9] IMPLICIT UniqueIdentifier OPTIONAL, 634 authentSig[10] Signature 635 } 637 The kdc-cert must have as its root certification one of the 638 certifiers sent to the KDC with the original request. If the KDC 639 has no such certification, then it will instead reply with a 640 KRB_ERROR of type KDC_ERROR_PREAUTH_FAILED. If a zero-length 641 root-cert was sent by the client as part of the PA-PK-AS-ROOT, then 642 a correspondingly zero-length kdc-cert may be absent, in which case 643 the client uses its copy of the KDC's public key. In the case of 644 recovery, the client uses its copy of the backup KDC public key. 646 Upon receipt of the response from the KDC, the client will verify 647 the public key for the KDC from PA-PK-AS-REP preauthentication data 648 field. The certificate must certify the key as belonging to a 649 principal whose name can be derived from the realm name. If the 650 certificate checks out, the client then decrypts the EncPaPkAsRepPart 651 and verifies the signature of the KDC. It then uses the random key 652 contained therein to decrypt the rest of the response, and continues 653 as per RFC 1510. Because there is direct trust between the user and 654 the KDC, the transited field of the ticket returned by the KDC should 655 remain empty. (Cf. Section 3.3.) 657 Examples 659 We now give several examples illustrating the protocols in this 660 section. Encryption of message M with key K is denoted {M}K and 661 the signature of message M with key K is denoted [M]K. 663 Example 1: The requesting user principal needs to be recovered and 664 uses only new clients. The recovery algorithm is Diffie Hellman (DH). 665 Then the exchange sequence between the user principal and the KDC is: 667 Client --------> AS_REQ (with or without preauth) --------> KDC 669 Client <--- KRB_ERROR (error code KDC_RECOVERY_NEEDED) <--- KDC 670 error data: [nonce, algID (DH), KDC DH public parameter, 671 KDC DH ID, KDC PublicKey Kvno and PublicKey, 672 KDC Salt]Signed with KDC PrivateKey 674 At this point, the client validates the KDC signature, checks to 675 see if the nonce is the same as the one in the AS_REQ, and stores 676 the new KDC public key and public key version number. The client 677 then generates a Diffie Hellman private parameter and computes 678 the corresponding Diffie Hellman public parameter; the client 679 also computes the shared Diffie Hellman symmetric key using the 680 KDC Diffie Hellman public parameter and its own Diffie Hellman 681 private parameter. Next, the client prompts the user for his/her 682 password (if it does not already have the password). The password 683 is concatenated with the KDC Salt and then SHA1 hashed; the 684 result is fed into the string to key function to obtain the new 685 user DES key. 687 The new user DES key will be encrypted (along with the AS_REQ 688 nonce) using the Diffie Hellman symmetric key and sent to the 689 KDC in the new AS_REQ message: 691 Client -> AS_REQ with preauth: rootCert, [PKAuthenticator with 692 user DH public parameter, {newUser DES key, nonce}DH 693 symmetric key, KDC DH ID]Signed with User PrivateKey 694 -> KDC 696 The KDC DH ID is copied by the client from the KDC_ERROR message 697 received above. Upon receipt and validation of this message, the 698 KDC first uses the KDC DH ID as an index to locate its 699 private Diffie Hellman parameter; it uses this parameter in 700 combination with the user public Diffie Hellman parameter 701 to compute the symmetric Diffie Hellman key. The KDC checks 702 if the encrypted nonce is the same as the one in the 703 PKAuthenticator and the AS_REQ part. The KDC then enters 704 the new user DES key into the database, resets the recovery 705 needed bit, and sets the valid symmetric key in database 706 bit. The KDC then creates the AS_REP message: 708 Client <-- AS_REP with preauth: kdcCert, {encReplyKey, 709 nonce}DH symmetric key <-------------------- KDC 711 The AS_REP encrypted part is encrypted with the encReplyKey 712 that is generated on the KDC. The nonces are copied from the 713 client AS_REQ. The kdcCert is a sequence of certificates 714 that have been certified by certifiers listed in the client 715 rootCert field, unless a zero length rootCert field was sent. 716 In the last case, the kdcCert will also have zero length. 718 3.2.2. Private key held by KDC 720 Implementation of the changes in this section is RECOMMENDED. 722 When the user's private key is not carried with the user, the 723 user may encrypt the private key using conventional cryptography, 724 and register the encrypted private key with the KDC. As 725 described in the previous section, the SHA1 hash of the password 726 concatenated with the kdcSalt is also stored in the KDC database 727 if the user only uses new clients. We restrict users of this 728 protocol to using new clients only. The reason for this restriction 729 is that it is not secure to store both the user private key 730 encrypted in the user's password and the user password on the KDC 731 simultaneously. 733 There are several options for storing private keys. If the 734 user stores their private key on a removable disk, it is 735 less convenient since they need to always carry the disk 736 around with them; in addition, the procedures for extracting 737 the key may vary between different operating systems. 738 Alternatively, the user can store a private key on the hard 739 disks of systems that he/she uses; besides limiting the 740 systems that the user can login from there is also a 741 greater security risk to the private key. If smart card 742 readers or slots are deployed in an organization, then the 743 user can store his/her private key on a smart card. Finally, 744 the user can store his/her private key encrypted in a password 745 on the KDC. This last option is probably the most practical 746 option currently; it is important that a good password policy 747 be used. 749 When the user's private key is stored on the KDC, 750 preauthentication is required. There are two cases depending on 751 whether the requesting user principal needs to be recovered. 753 In order to obtain its private key, a user principal includes the 754 padata type PA-PK-AS-REQ in the preauthentication data 755 field of the AS_REQ message. The accompanying pa-data field is: 757 PA-PK-AS-REQ ::= SEQUENCE { 758 algorithmId[0] INTEGER, -- Public Key Alg. 759 encClientPubVal[1] EncryptedData -- EncPaPkAsReqDH 760 -- (encrypted with key 761 -- K1) 762 } 764 EncPaPkAsReqDH ::= SEQUENCE { 765 clientPubValue[0] SubjectPublicKeyInfo 766 } 768 Pictorially, PA-PK-AS-REQ is algorithmID, {clientPubValue}K1. 770 The user principal sends its Diffie-Hellman public value encrypted 771 in the key K1. The key K1 is derived by performing string to key on 772 the SHA1 hash of the user password concatenated with the kdcSalt 773 which is stored in the /krb5/salt file. If the file is absent, 774 the concatenation step is skipped in the above algorithm. The 775 Diffie Hellman parameters g and p are implied by the algorithmID 776 field. By choosing g and p correctly, dictionary attacks against 777 the key K1 can be made more difficult [Jaspan]. 779 If the requesting user principal needs recovery, the encrypted 780 user private key is stored in the KDC database, and the AS_REQ 781 RecoveryData field is not present in the PKAuthenticator, then 782 the KDC replies with a KRB_ERROR message, with msg-type set to 783 KDC_ERR_PREAUTH_REQUIRED, and e-data set to: 785 PA-PK-AS-INFO ::= SEQUENCE { 786 signedDHErr SignedDHError, -- signed by KDC 787 encUserKey OCTET STRING OPTIONAL -- encrypted by 788 -- user password 789 -- key; (recovery 790 -- response) 792 } 794 The user principal should then continue with the section 3.2.1.1 795 protocol using the Diffie Hellman algorithm. 797 We now assume that the requesting user principal does not need 798 recovery. 800 Upon receipt of the authentication request with the PA-PK-AS-REQ, 801 the KDC generates the AS response as defined in RFC 1510, but 802 additionally includes a preauthentication field of type 803 PA-PK-USER-KEY. 805 PA-PK-USER-KEY ::= SEQUENCE { 806 kdcCert SEQUENCE OF Certificate, 807 encUserKeyPart EncryptedData, -- EncPaPkUserKeyPart 808 kdcPrivKey KDCPrivKey, 809 kdcPrivKeySig Signature 810 } 812 The kdc-cert field is identical to that in the PA-PK-AS-REP 813 preauthentication data field returned with the KDC response, and 814 must be validated as belonging to the KDC in the same manner. 816 KDCPrivKey ::= SEQUENCE { 817 nonce INTEGER, -- From AS_REQ 818 algorithmId INTEGER, -- DH algorithm 819 kdcPubValue SubjectPublicKeyInfo, -- DH algorithm 820 kdcSalt OCTET STRING -- Since user 821 -- uses only new 822 -- clients 823 } 825 The KDCPrivKey field is signed using the KDC private key. 826 The encrypted part of the AS_REP message is encrypted using the 827 Diffie Hellman derived symmetric key, as is the EncPaPkUserKeyPart. 829 EncPaPkUserKeyPart ::= SEQUENCE { 830 encUserKey OCTET STRING, 831 nonce INTEGER -- From AS_REQ 832 } 834 Notationally, if encryption algorithm A is used, then enc-key-part 835 is 836 A ({encUserKey, nonce}, Diffie-Hellman-symmetric-key). 838 If the client has used an incorrect kdcSalt to compute the 839 key K1, then the client needs to resubmit the above AS_REQ 840 message using the correct kdcSalt field from the KDCPrivKey 841 field. 843 This message contains the encrypted private key that has been 844 registered with the KDC by the user, as encrypted by the user, 845 super-encrypted with the Diffie Hellman derived symmetric key. 846 Because there is direct trust between the user and the KDC, the 847 transited field of the ticket returned by the KDC should remain 848 empty. (Cf. Section 3.3.) 850 Examples 852 We now give several examples illustrating the protocols in this 853 section. 855 Example 1: The requesting user principal needs to be recovered 856 and stores his/her encrypted private key on the KDC. Then the 857 exchange sequence between the user principal and the KDC is: 859 Client --------> AS_REQ (with or without preauth) -----> KDC 861 Client <--- KRB_ERROR (error code KDC_ERR_PREAUTH_REQUIRED) 862 error data: [nonce, algID (DH), KDC DH public 863 parameter, KDC DH ID, KDC PublicKey 864 Kvno and PublicKey, KDC Salt]Signed 865 with KDC PrivateKey, {user private 866 key}user password <------------- KDC 868 The protocol now continues with the second AS_REQ as in Example 869 1 of section 3.2.1.1. 871 Example 2: The requesting user principal does not need to be 872 recovered and stores his/her encrypted private key on the KDC. 873 Then the exchange sequence between the user principal and the KDC 874 when the user principal wants to obtain his/her private key is: 876 Client -> AS_REQ with preauth: algID, 877 {DH public parameter}K1 -> KDC 879 The key K1 is generated by using the string to key function 880 on the SHA1 hash of the password concatenated with the kdcSalt 881 from the /krb5/salt file. If the file is absent, then 882 the concatenation step is skipped, and the client will learn 883 the correct kdcSalt in the following AS_REP message from the 884 KDC. The algID should indicate some type of Diffie Hellman 885 algorithm. 887 The KDC replies with the AS_REP message with a preauthentication 888 data field: 890 Client <-- AS_REP with preauth: kdcCert, {encUserKey, <-- KDC 891 nonce}DH symmetric key, [nonce, algID, DH 892 public parameter, kdcSalt]KDC privateKey 893 The client validates the KDC's signature and checks that 894 the nonce matches the nonce in its AS_REQ message. 895 If the kdcSalt does not match what the client used, it 896 starts the protocol over. The client then uses the KDC 897 Diffie Hellman public parameter along with its own Diffie 898 Hellman private parameter to compute the Diffie Hellman 899 symmetric key. This key is used to decrypt the encUserKey 900 field; the client checks if the nonce matches its AS_REQ 901 nonce. At this point, the initial authentication protocol 902 is complete. 904 Example 3: The requesting user principal does not need to be 905 recovered and stores his/her encrypted private key on the KDC. 906 In this example, the user principal uses the conventional 907 symmetric key Kerberos V5 initial authentication protocol 908 exchange. 910 We note that the conventional protocol exposes the user 911 password to dictionary attacks; therefore, the user password 912 must be changed more often. An example of when this protocol 913 would be used is when new clients have been installed but an 914 organization has not phased in public key authentication for 915 all clients due to performance concerns. 917 Client ----> AS_REQ with preauthentication: {time}K1 --> KDC 919 Client <-------------------- AS_REP <------------------ KDC 921 The key K1 is derived as in the preceding two examples. 923 3.3. Clients with a public key certified by an outside authority 925 Implementation of the changes in this section is OPTIONAL. 927 In the case where the client is not registered with the current 928 KDC, the client is responsible for obtaining the private key on 929 its own. The client will request initial tickets from the KDC 930 using the TGS exchange, but instead of performing 931 preauthentication using a Kerberos ticket granting ticket, or 932 with the PA-PK-AS-REQ that is used when the public key is known 933 to the KDC, the client performs preauthentication using the 934 preauthentication data field of type PA-PK-AS-EXT-CERT: 936 PA-PK-AS-EXT-CERT ::= SEQUENCE { 937 userCert[0] SEQUENCE OF OCTET STRING, 938 signedAuth[1] SignedPKAuthenticator 939 } 941 where the user-cert specification depends on the type of 942 certificate that the user possesses. In cases where the service 943 has separate key pairs for digital signature and for encryption, 944 we recommend that the signature keys be used for the purposes of 945 sending the preauthentication (and deciphering the response). 947 The authenticator is the one used from the exchange in section 948 3.2.1, except that it is signed using the private key corresponding 949 to the public key in the user-cert. 951 The KDC will verify the preauthentication authenticator, and check the 952 certification path against its own policy of legitimate certifiers. 953 This may be based on a certification hierarchy, or simply a list of 954 recognized certifiers in a system like PGP. 956 If all checks out, the KDC will issue Kerberos credentials, as in 3.2, 957 but with the names of all the certifiers in the certification path 958 added to the transited field of the ticket, with a principal name 959 taken from the certificate (this might be a long path for X.509, or a 960 string like "John Q. Public " if the certificate 961 was a PGP certificate. The realm will identify the kind of 962 certificate and the final certifier as follows: 964 cert_type/final_certifier 966 as in PGP/. 968 3.4. Digital Signature 970 Implementation of the changes in this section is OPTIONAL. 972 We offer this option with the warning that it requires the client 973 process to generate a random DES key; this generation may not 974 be able to guarantee the same level of randomness as the KDC. 976 If a user registered a digital signature key pair with the KDC, 977 a separate exchange may be used. The client sends a KRB_AS_REQ 978 as described in section 3.2.2. If the user's database record 979 indicates that a digital signature key is to be used, then the 980 KDC sends back a KRB_ERROR as in section 3.2.2. 982 It is assumed here that the signature key is stored on local disk. 983 The client generates a random key of enctype ENCTYPE_DES_CBC_CRC, 984 signs it using the signature key (otherwise the signature is 985 performed as described in section 3.2.1), then encrypts the whole 986 with the public key of the KDC. This is returned with a separate 987 KRB_AS_REQ in a preauthentication of type 989 PA-PK-AS-SIGNED ::= SEQUENCE { 990 signedKey[0] EncryptedData -- PaPkAsSignedData 991 } 993 PaPkAsSignedData ::= SEQUENCE { 994 signedKeyPart[0] SignedKeyPart, 995 signedKeyAuth[1] PKAuthenticator, 996 sig[2] Signature 997 } 999 SignedKeyPart ::= SEQUENCE { 1000 encSignedKey[0] EncryptionKey, 1001 nonce[1] INTEGER 1002 } 1003 where the nonce is the one from the request. Upon receipt of the 1004 request, the KDC decrypts, then verifies the random key. It then 1005 replies as per RFC 1510, except that instead of being encrypted 1006 with the password-derived DES key, the reply is encrypted using 1007 the randomKey sent by the client. Since the client already knows 1008 this key, there is no need to accompany the reply with an extra 1009 preauthentication field. Because there is direct trust between 1010 the user and the KDC, the transited field of the ticket returned 1011 by the KDC should remain empty. (Cf. Section 3.3.) 1013 In the event that the KDC database indicates that the user 1014 principal must be recovered, and the PKAuthenticator does not 1015 contain the RecoveryData field, the KDC will reply with the 1016 KDC_RECOVERY_NEEDED error. The user principal then sends 1017 another AS_REQ message that includes the RecoveryData field 1018 in the PKAuthenticator. The AS_REP message is the same as 1019 in the basic Kerberos V5 protocol. 1021 4. Preauthentication Data Types 1023 We propose that the following preauthentication types be allocated 1024 for the preauthentication data packages described in this draft: 1026 #define KRB5_PADATA_ROOT_CERT 17 /* PA-PK-AS-ROOT */ 1027 #define KRB5_PADATA_PUBLIC_REP 18 /* PA-PK-AS-REP */ 1028 #define KRB5_PADATA_PUBLIC_REQ 19 /* PA-PK-AS-REQ */ 1029 #define KRB5_PADATA_PRIVATE_REP 20 /* PA-PK-USER-KEY */ 1030 #define KRB5_PADATA_PUBLIC_EXT 21 /* PA-PK-AS-EXT-CERT */ 1031 #define KRB5_PADATA_PUBLIC_SIGN 22 /* PA-PK-AS-SIGNED */ 1033 5. Encryption Information 1035 For the public key cryptography used in direct registration, we 1036 used (in our implementation) the RSAREF library supplied with the 1037 PGP 2.6.2 release. Encryption and decryption functions were 1038 implemented directly on top of the primitives made available 1039 therein, rather than the fully sealing operations in the API. 1041 6. Compatibility with One-Time Passcodes 1043 We solicit discussion on how the use of public key cryptography 1044 for initial authentication will interact with the proposed use of 1045 one time passwords discussed in Internet Draft 1046 . 1048 7. Strength of Encryption and Signature Mechanisms 1050 In light of recent findings on the strengths of MD5 and various DES 1051 modes, we solicit discussion on which modes to incorporate into the 1052 protocol changes. 1054 8. Expiration 1056 This Internet-Draft expires on April 19, 1997. 1058 9. Authors' Addresses 1060 B. Clifford Neuman 1061 USC/Information Sciences Institute 1062 4676 Admiralty Way Suite 1001 1063 Marina del Rey, CA 90292-6695 1065 Phone: 310-822-1511 1066 EMail: bcn@isi.edu 1068 Brian Tung 1069 USC/Information Sciences Institute 1070 4676 Admiralty Way Suite 1001 1071 Marina del Rey, CA 90292-6695 1073 Phone: 310-822-1511 1074 EMail: brian@isi.edu 1076 John Wray 1077 Digital Equipment Corporation 1078 550 King Street, LKG2-2/Z7 1079 Littleton, MA 01460 1081 Phone: 508-486-5210 1082 EMail: wray@tuxedo.enet.dec.com 1084 Jonathan Trostle 1085 CyberSafe Corporation 1086 1605 NW Sammamish Rd., Suite 310 1087 Issaquah, WA 98027-5378 1089 Phone: 206-391-6000 1090 EMail: jonathan.trostle@cybersafe.com