tls.lisp (25156B)
1 ;;; Copyright (C) 2014 Tomas Hlavaty <tom@logand.com> 2 ;;; 3 ;;; Permission is hereby granted, free of charge, to any person 4 ;;; obtaining a copy of this software and associated documentation 5 ;;; files (the "Software"), to deal in the Software without 6 ;;; restriction, including without limitation the rights to use, copy, 7 ;;; modify, merge, publish, distribute, sublicense, and/or sell copies 8 ;;; of the Software, and to permit persons to whom the Software is 9 ;;; furnished to do so, subject to the following conditions: 10 ;;; 11 ;;; The above copyright notice and this permission notice shall be 12 ;;; included in all copies or substantial portions of the Software. 13 ;;; 14 ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 ;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 ;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 ;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 ;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 ;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 ;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 ;;; DEALINGS IN THE SOFTWARE. 22 23 (defpackage :rw.tls 24 (:use :cl)) 25 26 (in-package :rw.tls) 27 28 ;; broken stuff: rc4 md5 sha1 aescbc rsa1024 rsa-keyxchg ecdsa 29 30 ;; good: dhe ecdhe aesgcm pfs; better 512hash rsa4096+ aes256+ 31 32 ;;tshark -i wlp3s0 -V >~/git/cl-rw/tls.log 33 ;;gnutls-cli wikipedia.org 34 35 ;; https://en.wikipedia.org/wiki/Transport_Layer_Security 36 ;; http://msdn.microsoft.com/en-us/library/windows/desktop/aa380513(v=vs.85).aspx 37 ;; http://technet.microsoft.com/en-us/library/cc785811(v=ws.10).aspx 38 ;; https://tools.ietf.org/html/rfc5246 39 ;; https://tools.ietf.org/html/rfc4492 40 41 (rw.wire:defenum $AlertLevel (:type rw:u8) 42 (WARNING . 1) 43 (FATAL . 2)) 44 45 (rw.wire:defenum $AlertDescription (:type rw:u8) 46 (CLOSE_NOTIFY . 0) 47 (UNEXPECTED_MESSAGE . 10) 48 (BAD_RECORD_MAC . 20) 49 (DECRYPTION_FAILED_RESERVED . 21) 50 (RECORD_OVERFLOW . 22) 51 (DECOMPRESSION_FAILURE . 30) 52 (HANDSHAKE_FAILURE . 40) 53 (NO_CERTIFICATE_RESERVED . 41) 54 (BAD_CERTIFICATE . 42) 55 (UNSUPPORTED_CERTIFICATE . 43) 56 (CERTIFICATE_REVOKED . 44) 57 (CERTIFICATE_EXPIRED . 45) 58 (CERTIFICATE_UNKNOWN . 46) 59 (ILLEGAL_PARAMETER . 47) 60 (UNKNOWN_CA . 48) 61 (ACCESS_DENIED . 49) 62 (DECODE_ERROR . 50) 63 (DECRYPT_ERROR . 51) 64 (EXPORT_RESTRICTION_RESERVED . 60) 65 (PROTOCOL_VERSION . 70) 66 (INSUFFICIENT_SECURITY . 71) 67 (INTERNAL_ERROR . 80) 68 (USER_CANCELED . 90) 69 (NO_RENEGOTIATION . 100) 70 (UNSUPPORTED_EXTENSION . 110)) 71 72 (rw.wire:defenum $CipherSuite (:type rw:u16be) 73 (TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA . #X0013) 74 (TLS_DHE_DSS_WITH_AES_128_CBC_SHA . #X0032) 75 (TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 . #X0040) 76 (TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 . #X00A2) 77 (TLS_DHE_DSS_WITH_AES_256_CBC_SHA . #X0038) 78 (TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 . #X006A) 79 (TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 . #X00A3) 80 (TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA . #X0044) 81 (TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 . #X00BD) 82 (TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 . #XC080) 83 (TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA . #X0087) 84 (TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 . #X00C3) 85 (TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 . #XC081) 86 (TLS_DHE_DSS_WITH_RC4_128_SHA . #X0066) 87 (TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA . #X0016) 88 (TLS_DHE_RSA_WITH_AES_128_CBC_SHA . #X0033) 89 (TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 . #X0067) 90 (TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 . #X009E) 91 (TLS_DHE_RSA_WITH_AES_256_CBC_SHA . #X0039) 92 (TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 . #X006B) 93 (TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 . #X009F) 94 (TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA . #X0045) 95 (TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 . #X00BE) 96 (TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 . #XC07C) 97 (TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA . #X0088) 98 (TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 . #X00C4) 99 (TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 . #XC07D) 100 (TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA . #X001B) 101 (TLS_DH_ANON_WITH_AES_128_CBC_SHA . #X0034) 102 (TLS_DH_ANON_WITH_AES_128_CBC_SHA256 . #X006C) 103 (TLS_DH_ANON_WITH_AES_256_CBC_SHA . #X003A) 104 (TLS_DH_ANON_WITH_AES_256_CBC_SHA256 . #X006D) 105 (TLS_DH_ANON_WITH_RC4_128_MD5 . #X0018) 106 (TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA . #X000D) 107 (TLS_DH_DSS_WITH_AES_128_CBC_SHA . #X0030) 108 (TLS_DH_DSS_WITH_AES_128_CBC_SHA256 . #X003E) 109 (TLS_DH_DSS_WITH_AES_256_CBC_SHA . #X0036) 110 (TLS_DH_DSS_WITH_AES_256_CBC_SHA256 . #X0068) 111 (TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA . #X0010) 112 (TLS_DH_RSA_WITH_AES_128_CBC_SHA . #X0031) 113 (TLS_DH_RSA_WITH_AES_128_CBC_SHA256 . #X003F) 114 (TLS_DH_RSA_WITH_AES_256_CBC_SHA . #X0037) 115 (TLS_DH_RSA_WITH_AES_256_CBC_SHA256 . #X0069) 116 (TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA . #XC008) 117 (TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA . #XC009) 118 (TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 . #XC023) 119 (TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 . #XC02B) 120 (TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA . #XC00A) 121 (TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 . #XC024) 122 (TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 . #XC02C) 123 (TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 . #XC072) 124 (TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 . #XC086) 125 (TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 . #XC073) 126 (TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 . #XC087) 127 (TLS_ECDHE_ECDSA_WITH_RC4_128_SHA . #XC007) 128 (TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA . #XC012) 129 (TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA . #XC013) 130 (TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 . #XC027) 131 (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 . #XC02F) 132 (TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA . #XC014) 133 (TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 . #XC028) 134 (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 . #XC030) 135 (TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 . #XC076) 136 (TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 . #XC08A) 137 (TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 . #XC077) 138 (TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 . #XC08B) 139 (TLS_ECDHE_RSA_WITH_RC4_128_SHA . #XC011) 140 (TLS_NULL_WITH_NULL_NULL . #X0000) 141 (TLS_RSA_WITH_3DES_EDE_CBC_SHA . #X000A) 142 (TLS_RSA_WITH_AES_128_CBC_SHA . #X002F) 143 (TLS_RSA_WITH_AES_128_CBC_SHA256 . #X003C) 144 (TLS_RSA_WITH_AES_128_GCM_SHA256 . #X009C) 145 (TLS_RSA_WITH_AES_256_CBC_SHA . #X0035) 146 (TLS_RSA_WITH_AES_256_CBC_SHA256 . #X003D) 147 (TLS_RSA_WITH_AES_256_GCM_SHA384 . #X009D) 148 (TLS_RSA_WITH_CAMELLIA_128_CBC_SHA . #X0041) 149 (TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 . #X00BA) 150 (TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 . #XC07A) 151 (TLS_RSA_WITH_CAMELLIA_256_CBC_SHA . #X0084) 152 (TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 . #X00C0) 153 (TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 . #XC07B) 154 (TLS_RSA_WITH_NULL_MD5 . #X0001) 155 (TLS_RSA_WITH_NULL_SHA . #X0002) 156 (TLS_RSA_WITH_NULL_SHA256 . #X003B) 157 (TLS_RSA_WITH_RC4_128_MD5 . #X0004) 158 (TLS_RSA_WITH_RC4_128_SHA . #X0005)) 159 160 (rw.wire:defenum $ClientCertificateType (:type rw:u8) 161 (rsa_sign . 1) 162 (dss_sign . 2) 163 (rsa_fixed_dh . 3) 164 (dss_fixed_dh . 4) 165 (rsa_ephemeral_dh_RESERVED . 5) 166 (dss_ephemeral_dh_RESERVED . 6) 167 (fortezza_dms_RESERVED . 20)) 168 169 (rw.wire:defenum $CompressionMethod (:type rw:u8) 170 (null . 0)) 171 172 (rw.wire:defenum $ContentType (:type rw:u8) 173 (CHANGE_CIPHER_SPEC . 20) 174 (ALERT . 21) 175 (HANDSHAKE . 22) 176 (APPLICATION_DATA . 23)) 177 178 (rw.wire:defenum $ContentVersion (:type rw:u16be) 179 (SSL3.0 . #x0300) 180 (TLS1.2 . #x0303)) 181 182 (rw.wire:defenum $ExtensionType (:type rw:u16be) 183 (ec_point_formats . #x000b) 184 (elliptic_curves . #x000a) 185 (renegotiation_info . #xff01) 186 (SessionTicket_TLS . #x0023) 187 (server_name . #x0000) 188 (signature_algorithms . #x000d) 189 (status_request . #x0005)) 190 191 (rw.wire:defenum $HandshakeType (:type rw:u8) 192 (HELLO_REQUEST . 0) 193 (CLIENT_HELLO . 1) 194 (SERVER_HELLO . 2) 195 (CERTIFICATE . 11) 196 (SERVER_KEY_EXCHANGE . 12) 197 (CERTIFICATE_REQUEST . 13) 198 (SERVER_HELLO_DONE . 14) 199 (CERTIFICATE_VERIFY . 15) 200 (CLIENT_KEY_EXCHANGE . 16) 201 (FINISHED . 20)) 202 203 (rw.wire:defenum $HashAlgorithm (:type rw:u8) 204 (none . 0) 205 (md5 . 1) 206 (sha1 . 2) 207 (sha224 . 3) 208 (sha256 . 4) 209 (sha384 . 5) 210 (sha512 . 6)) 211 212 (rw.wire:defenum $ECCurveType (:type rw:u8) 213 (explicit_prime . 1) 214 (explicit_char2 . 2) 215 (named_curve . 3) 216 #+nil(reserved 248..255)) 217 218 (rw.wire:defenum $NamedCurve (:type rw:u16be) 219 (sect163k1 . 1) 220 (sect163r1 . 2) 221 (sect163r2 . 3) 222 (sect193r1 . 4) 223 (sect193r2 . 5) 224 (sect233k1 . 6) 225 (sect233r1 . 7) 226 (sect239k1 . 8) 227 (sect283k1 . 9) 228 (sect283r1 . 10) 229 (sect409k1 . 11) 230 (sect409r1 . 12) 231 (sect571k1 . 13) 232 (sect571r1 . 14) 233 (secp160k1 . 15) 234 (secp160r1 . 16) 235 (secp160r2 . 17) 236 (secp192k1 . 18) 237 (secp192r1 . 19) 238 (secp224k1 . 20) 239 (secp224r1 . 21) 240 (secp256k1 . 22) 241 (secp256r1 . 23) 242 (secp384r1 . 24) 243 (secp521r1 . 25) 244 ;;reserved (0xfe00..0xfeff) 245 (arbitrary_explicit_prime_curves . #xff01) 246 (arbitrary_explicit_char2_curves . #xff02)) 247 248 (rw.wire:defenum %$SignatureHashAlgorithmSignature (:type rw:u8) 249 (rsa . 1)) 250 251 (rw.wire:defenum $ECPointFormat (:type rw:u8) 252 (uncompressed . 0) 253 (ansiX962_compressed_prime . 1) 254 (ansiX962_compressed_char2 . 2) 255 #+nil(reserved 248..255)) 256 257 (defun PublicValueEncoding () 258 ;;'implicit 259 'explicit) 260 261 (defun KeyExchangeAlgorithm () 262 ;;'ecdhe_rsa 263 'ec_diffie_hellman) 264 265 ;; (rw.wire:defenum $KeyExchangeAlgorithm (:type rw:u8) 266 ;; (dhe_dss . 0) 267 ;; (dhe_rsa . 1) 268 ;; (dh_anon . 2) 269 ;; (rsa . 3) 270 ;; (dh_dss . 4) 271 ;; (dh_rsa . 5)) 272 273 ;; ECDH_ECDSA Fixed ECDH with ECDSA-signed certificates. 274 ;; ECDHE_ECDSA Ephemeral ECDH with ECDSA signatures. 275 ;; ECDH_RSA Fixed ECDH with RSA-signed certificates. 276 ;; ECDHE_RSA Ephemeral ECDH with RSA signatures. 277 ;; ECDH_anon Anonymous ECDH, no signatures. 278 279 ;; (defun ECBasisType () 280 ;; 'ec_basis_trinomial 281 ;; 'ec_basis_pentanomial) 282 283 (defun SignatureAlgorithm () 284 ;;'anonymous 285 ;;'rsa 286 ;;'dsa 287 'ecdsa) 288 289 (rw.wire:defstruc $Alert () 290 ($AlertLevel level) 291 ($AlertDescription description)) 292 293 #+nil 294 (rw.wire:defstruc $ASN.1Cert () 295 (rw:u8 data :min 0 :max #.(1- (expt 2 24)))) 296 297 (rw.wire:defstruc %$Certificate () 298 (rw:u8 #+nil $ASN.1Cert data :length rw:u24be :min 0 :max #.(1- (expt 2 24))) 299 (rw.wire::computed der :next (rw.der:next-der (rw:reader data)))) 300 301 (rw.wire:defstruc $Certificate () 302 (%$Certificate list :length rw:u24be :min 0 :max #.(1- (expt 2 24)) :size t)) 303 304 (rw.wire:defstruc %$ECPointFormatList () 305 ($ECPointFormat ec_point_format_list :length rw:u8 :min 1 :size t)) 306 307 (rw.wire:defstruc $ECPointFormatList () 308 (%$ECPointFormatList data :length rw:u16be)) 309 310 (rw.wire:defstruc $Extension () 311 ($ExtensionType type) 312 ((ecase type 313 ;;(status_request) 314 ;;(server_name) 315 ;;(renegotiation_info) 316 ;;(SessionTicket_TLS) 317 ;;(elliptic_curves) 318 (ec_point_formats $ECPointFormatList) 319 #+nil(signature_algorithms)) 320 data) 321 #+nil(rw:u8 data :length rw:u16be :min 0 :max #.(1- (expt 2 16)) :size t)) 322 323 (rw.wire:defstruc $ClientHello () 324 ($ContentVersion #+nil $ProtocolVersion version) 325 ($Random random) 326 ($SessionID session_id) 327 ($CipherSuite cipher_suites :length rw:u16be :min 2 :max #.(- (expt 2 16) 2) :size t) 328 ($CompressionMethod compression_methods :length rw:u8 :min 1 :max #.(1- (expt 2 8)) :size t) 329 ($Extension extensions :length rw:u16be :min 0 :max #.(1- (expt 2 16)) :size t)) 330 331 (rw.wire:defstruc $ServerDHParams () 332 (rw:u8 dh_p :length rw:u16be :min 1 :max #.(1- (expt 2 16))) 333 (rw:u8 dh_g :length rw:u16be :min 1 :max #.(1- (expt 2 16))) 334 (rw:u8 dh_Ys :length rw:u16be :min 1 :max #.(1- (expt 2 16)))) 335 336 (rw.wire:defstruc $signed_params () 337 (rw:u8 client_random :size 32) 338 (rw:u8 server_random :size 32) 339 ($ServerDHParams params2)) 340 341 (rw.wire:defstruc %$ServerDHParams () 342 ($ServerDHParams params) 343 ($signed_params signed_params)) 344 345 (rw.wire:defstruc $ECCurve () 346 (rw:u8 a :length rw:u8 :min 1) 347 (rw:u8 b :length rw:u8 :min 1)) 348 349 ;;http://stackoverflow.com/questions/10936171/how-do-i-compress-or-encode-the-elliptic-curve-public-key-and-put-it-over-the-ne 350 (rw.wire:defstruc $ECPoint () 351 ;;(rw:u8 data :length rw:u8 :min 1 :size t) 352 (rw:u8 length) 353 (rw:u8 #+nil $ECPointFormat format #+nil :check #+nil(= 4 format)) ;; 4=uncompressed 2|3=compressed 354 ;;(rw.wire::computed format :compute (progn (assert (= 4 %format)) %format)) 355 (rw:u8 x :size (floor length 2)) 356 (rw:u8 y :size (floor length 2))) 357 358 359 ;; (rw.wire:defstruc %$ExplicitPrime () 360 ;; opaque prime_p <1..2^8-1> 361 ;; ECCurve curve 362 ;; ECPoint base 363 ;; opaque order <1..2^8-1> 364 ;; opaque cofactor <1..2^8-1>) 365 366 ;; (rw.wire:defstruc %$ExplicitChar2 () 367 ;; uint16 m 368 ;; ECBasisType basis 369 ;; select (basis) { 370 ;; case ec_trinomial: 371 ;; opaque k <1..2^8-1> 372 ;; case ec_pentanomial: 373 ;; opaque k1 <1..2^8-1> 374 ;; opaque k2 <1..2^8-1> 375 ;; opaque k3 <1..2^8-1> 376 ;; } 377 ;; ECCurve curve 378 ;; ECPoint base 379 ;; opaque order <1..2^8-1> 380 ;; opaque cofactor <1..2^8-1>) 381 382 (rw.wire:defstruc $ECParameters () 383 ($ECCurveType curve_type) 384 ((ecase curve_type 385 ;;(explicit_prime %$ExplicitPrime) 386 ;;(explicit_char2 %$ExplicitChar2) 387 (named_curve $NamedCurve)) 388 data)) 389 390 (rw.wire:defstruc $ServerECDHParams () 391 ($ECParameters curve_params) 392 ($ECPoint public)) 393 394 (rw.wire:defstruc %$SignatureHashAlgorithm () 395 ($HashAlgorithm hash) 396 (%$SignatureHashAlgorithmSignature signature)) 397 398 (rw.wire:defstruc %$ECSASignature () ;; digitally-signed 399 (%$SignatureHashAlgorithm algorithm) 400 (rw:u16be length #+nil :compute #+nil(ShaSize)) 401 (rw:u8 sha_hash :size length)) 402 403 (rw.wire:defstruc $Signature () 404 (rw.wire::computed algorithm :compute (SignatureAlgorithm)) 405 ((ecase algorithm 406 (ecdsa %$ECSASignature)) 407 data)) 408 409 (rw.wire:defstruc %$ServerECDHParams () 410 ($ServerECDHParams params) 411 ($Signature signed_params)) 412 413 (rw.wire:defstruc $ServerKeyExchange () 414 ;;(rw:u8 data :length rw:u16be :min 1 :max #.(1- (expt 2 16))) 415 (rw.wire::computed type :compute (KeyExchangeAlgorithm)) 416 ((ecase type 417 ;;(dh_anon $ServerDHParams) 418 ;;((dhe_dss dhe_rsa) %$ServerDHParams) 419 (ec_diffie_hellman %$ServerECDHParams) 420 #+nil((rsa dh_dss dh_rsa))) 421 data)) 422 423 (rw.wire:defstruc $SessionID () 424 (rw:u8 data :length rw:u8 :min 0 :max 32 :size t)) 425 426 (rw.wire:defstruc $Random () 427 (rw:u32be gmt_unix_time) 428 (rw:u8 random_bytes :size 28)) 429 430 (rw.wire:defstruc $ServerHello () 431 ($ContentVersion #+nil ProtocolVersion version) 432 ($Random random) 433 ($SessionID session_id) 434 ($CipherSuite cipher_suite) 435 ($CompressionMethod compression_method) 436 ($Extension extensions :length rw:u16be :min 0 :max #.(1- (expt 2 16)) :size t)) 437 438 (rw.wire:defstruc $dh_Yc () 439 (rw:u8 data :length rw:u16be :min 1 :max #.(1- (expt 2 16)))) 440 441 (rw.wire:defstruc $EncryptedPreMasterSecret () 442 ($PreMasterSecret pubkey_encrypted)) 443 444 (rw.wire:defstruc $ClientDiffieHellmanPublic () 445 (rw.wire::computed type :compute (PublicValueEncoding)) 446 ((ecase type 447 (implicit) 448 (explicit $dh_Yc)) 449 dh_public)) 450 451 (rw.wire:defstruc $ClientECDiffieHellmanPublic () 452 (rw.wire::computed type :compute (PublicValueEncoding)) 453 ((ecase type 454 (implicit) 455 (explicit $ECPoint)) ;; ecdh_Yc 456 ecdh_public)) 457 458 (rw.wire:defstruc $ClientKeyExchange () 459 (rw.wire::computed type :compute (KeyExchangeAlgorithm)) 460 ((ecase type 461 ;;(rsa $EncryptedPreMasterSecret) 462 ;;((dhe_dss dhe_rsa dh_dss dh_rsa dh_anon) $ClientDiffieHellmanPublic) 463 (ec_diffie_hellman $ClientECDiffieHellmanPublic)) 464 data)) 465 466 (rw.wire:defstruc $Handshake () 467 ($HandshakeType type) 468 ((ecase type 469 (CERTIFICATE $Certificate) 470 (CLIENT_HELLO $ClientHello) 471 (CLIENT_KEY_EXCHANGE $ClientKeyExchange) 472 (SERVER_HELLO $ServerHello) 473 (SERVER_HELLO_DONE) 474 (SERVER_KEY_EXCHANGE $ServerKeyExchange)) 475 data :length rw:u24be)) 476 477 (rw.wire:defstruc $PreMasterSecret () 478 ($ContentVersion #+nil ProtocolVersion client_version) 479 (rw:u8 random :size 46)) 480 481 (rw.wire:defstruc $Record () 482 ($ContentType type) 483 (rw:u16be #+nil ContentVersion version) 484 ((ecase type 485 (ALERT $Alert) 486 (HANDSHAKE $Handshake)) 487 data :length rw:u16be :min 1 :max 16383) 488 #+nil 489 (rw:u8 data :length rw:u16be :min 1 :max 16383 :size t)) 490 491 ;; struct { 492 ;; HashAlgorithm hash 493 ;; SignatureAlgorithm signature 494 ;; } SignatureAndHashAlgorithm 495 496 ;; SignatureAndHashAlgorithm 497 ;; supported_signature_algorithms<2..2^16-1> 498 499 (defun random-octets (length) 500 (loop 501 for i from 0 below length 502 collect (random 256))) 503 504 (defun universal-time-to-unix (x) 505 (- x #.(encode-universal-time 0 0 0 1 1 1970 0))) 506 507 ;;(universal-time-to-unix (encode-universal-time 19 22 23 28 7 2014 0)) ;; TODO broken 508 509 (defun write-client-hello (writer client-random client-hello-time) 510 (write-$Record 511 writer 512 (make-$Record 513 :type 'HANDSHAKE 514 :version ($ContentVersion 'SSL3.0) 515 :data (make-$Handshake 516 :type 'CLIENT_HELLO 517 :data (make-$ClientHello 518 :version 'TLS1.2 519 :random (make-$Random 520 :gmt_unix_time client-hello-time 521 :random_bytes client-random) 522 :session_id (make-$SessionID #+nil :data #+nil(random-octets 32)) 523 :cipher_suites '( 524 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 525 ;; TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 526 ;; TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 527 ) 528 :compression_methods (list 'null) 529 :extensions (list 530 #+nil 531 (make-$Extension :type 'status_request 532 :data '(1 0 0 0 0)) 533 #+nil 534 (make-$Extension :type 'server_name 535 :data '(0 #x10 0 0 #xd #x77 #x69 #x6b #x69 #x70 #x65 #x64 #x69 #x61 #x2e #x6f #x72 #x67)) 536 #+nil 537 (make-$Extension :type 'renegotiation_info 538 :data '(0)) 539 #+nil 540 (make-$Extension :type 'SessionTicket_TLS :data nil) 541 #+nil 542 (make-$Extension :type 'elliptic_curves ;; TODO 543 :data '(0 10 0 #x13 0 #x15 0 #x17 0 #x18 0 #x19)) 544 (make-$Extension 545 :type 'ec_point_formats ;; TODO 546 :data (make-$ECPointFormatList 547 :data 548 (make-%$ECPointFormatList 549 :ec_point_format_list 550 '(uncompressed)))) 551 #+nil 552 (make-$Extension :type 'signature_algorithms ;; TODO 553 :data '(0 #x1a 4 1 4 2 4 3 5 1 5 3 6 1 6 3 3 1 3 2 3 3 2 1 2 2 2 3)))))))) 554 555 (defun write-client-key-exchange (writer) 556 (write-$Record 557 writer 558 (make-$Record 559 :type 'HANDSHAKE 560 :version ($ContentVersion 'SSL3.0) 561 :data (make-$Handshake 562 :type 'CLIENT_KEY_EXCHANGE 563 :data (make-$ClientKeyExchange 564 :type 'dhe_rsa 565 :data (make-$ClientECDiffieHellmanPublic 566 :type 'explicit 567 :ecdh_public (make-$ECPoint 568 :length 65 569 :format 4 ;;'uncompressed 570 :x #(47 33 158 197 200 79 233 37 253 19 571 101 180 145 99 27 72 189 79 195 35 572 43 226 40 247 85 134 48 189 7 134 573 71 97) 574 :y #(26 90 191 31 48 24 153 65 243 211 575 213 24 113 9 11 139 111 253 83 190 576 215 197 143 219 71 194 44 136 240 577 78 112 25)))))))) 578 579 (defun next-server-hello (reader client-hello-time) 580 (let ((x (next-$Record reader))) 581 (let ((x ($Record-data x))) 582 (let ((x ($Handshake-data x))) 583 (assert (eq 'TLS1.2 ($ServerHello-version x))) 584 (assert (eq 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 585 ($ServerHello-cipher_suite x))) 586 (let ((x ($ServerHello-random x))) 587 (assert (<= 0 (- ($Random-gmt_unix_time x) client-hello-time) 1)) 588 ($Random-random_bytes x)) 589 ;; TODO server hello extensions 590 )))) 591 592 (defun next-server-certificate (reader) 593 (let ((x (next-$Record reader))) 594 (let ((x ($Record-data x))) 595 (let ((x ($Handshake-data x))) 596 (loop 597 for x in ($Certificate-list x) 598 collect (%$Certificate-der x)))))) 599 (defun der-decode-bit-string (x) 600 (destructuring-bind (tag m n) x 601 (assert (eq 'rw.der::bit-string tag)) 602 (assert (zerop m)) 603 (let* ((x (ash n m)) 604 (nbytes (ceiling (integer-length x) 8)) 605 (b (rw.wire:make-octet-buffer nbytes)) 606 (w (rw:writer b))) 607 (loop 608 for i from (1- nbytes) downto 0 609 do (rw:write-u8 w (ldb (byte 8 (* 8 i)) x))) 610 (rw.der:next-der (rw:reader b))))) 611 612 (defun certificate-r-s (x) 613 (labels ((rec (x) 614 (when (consp x) 615 (when (equal (car x) 616 '((rw.der::oid 1 2 840 113549 1 1 1) nil)) 617 (assert (not (cddr x))) 618 (destructuring-bind (r s) (der-decode-bit-string (cadr x)) 619 ;;(print (list :@@@ r s)) 620 (return-from certificate-r-s (values r s)))) 621 (mapc #'rec x)))) 622 (rec x))) 623 624 (defun next-server-key-exchange (reader client-random server-random server-certificates) 625 (certificate-r-s (car server-certificates)) ;; TODO r s 626 (let ((x (next-$Record reader))) 627 (let ((x ($Record-data x))) 628 (let ((x ($Handshake-data x))) 629 (assert (eq 'ec_diffie_hellman ($ServerKeyExchange-type x))) 630 (let ((x ($ServerKeyExchange-data x))) 631 (let ((x (%$serverecdhparams-params x))) 632 (let ((b (rw.wire:make-octet-buffer 42))) 633 (write-$ServerECDHParams (rw:writer b) x) 634 #+nil(print (list :@@@ :params b))) 635 (let ((x ($serverecdhparams-public x))) 636 )) 637 (let ((x (%$serverecdhparams-signed_params x))) 638 (assert (eq 'ecdsa ($signature-algorithm x))) 639 (let ((x ($signature-data x))) 640 (let ((hash (%$ecsasignature-sha_hash x))) 641 #+nil(print (list :@@@ :hash hash))))) 642 ;; TODO check signed params 643 (print x)))))) 644 645 (defun next-server-hello-done (reader) 646 (let ((x (next-$Record reader))) 647 ;;(print x) 648 (let ((x ($Record-data x))) 649 (assert (eq 'SERVER_HELLO_DONE ($Handshake-type x))) 650 (assert (not ($Handshake-data x)))))) 651 652 #+nil 653 (let ((saved (test))) 654 (with-open-file (s "/tmp/a" 655 :direction :output 656 :if-exists :supersede 657 :if-does-not-exist :create 658 :element-type '(unsigned-byte 8)) 659 (write-sequence saved s)) 660 (with-open-file (s "/tmp/a" :element-type '(unsigned-byte 8)) 661 (next-$Record (rw:byte-reader s)) 662 #+nil(next-$ClientHello (record-reader (rw:byte-reader s))))) 663 664 (defun %tls-connect (reader writer) 665 (let ((client-random (random-octets 28)) 666 (client-hello-time (universal-time-to-unix (get-universal-time)))) 667 (write-client-hello writer client-random client-hello-time) 668 (rw.wire:flush writer) 669 (let ((server-random (next-server-hello reader client-hello-time)) 670 (server-certificates (next-server-certificate reader))) 671 (next-server-key-exchange reader client-random server-random 672 server-certificates) 673 ;; TODO certificate request 674 (next-server-hello-done reader) 675 ;; TODO certificate 676 (write-client-key-exchange writer) 677 ;; TODO certificate verify 678 ;; change cipher spec <<<<<<<<<<<<<<<<<<<< 679 ;; multiple handshake messages 680 (rw.wire:flush writer) 681 (next-$Record reader) ;; expecting alert handshake failure 682 #+nil 683 (list (next-$Record r) ;; new session ticket 684 (next-$Record r) ;; change cipher spec 685 (next-$Record r) ;; encrypted handshake message 686 )))) 687 688 (defun tls-connect (hostname &optional (port 443)) 689 (with-open-stream (s (rw.socket:make-tcp-client-socket hostname port)) 690 (%tls-connect (rw:byte-reader s) (rw.wire:packet-writer s)))) 691 692 ;;(tls-connect "wikipedia.org") 693 ;;(tls-connect "127.1" 5556)