-2.422068 | /* -0.994997 | * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved. -0.934991 | * -0.003940 | * @APPLE_LICENSE_HEADER_START@ -0.387271 | * -0.001576 | * This file contains Original Code and/or Modifications of Original Code -0.000009 | * as defined in and that are subject to the Apple Public Source License -0.000025 | * Version 2.0 (the 'License'). You may not use this file except in -0.000071 | * compliance with the License. Please obtain a copy of the License at -0.000043 | * http://www.opensource.apple.com/apsl/ and read it before using this -0.000180 | * file. -0.017257 | * -0.000027 | * The Original Code and all software distributed under the License are -0.000044 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -0.000004 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -0.000037 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -0.000156 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -0.000006 | * Please see the License for the specific language governing rights and -0.000085 | * limitations under the License. -0.000308 | * -0.000127 | * @APPLE_LICENSE_HEADER_END@ -0.151461 | */ -0.142432 | -0.346417 | /* -1.807617 | * sslKeyExchange.c - Support for key exchange and server key exchange -0.642099 | */ -0.263607 | -0.264202 | #include "ssl.h" -0.465060 | #include "sslContext.h" -0.283336 | #include "sslHandshake.h" -0.506720 | #include "sslMemory.h" -0.254574 | #include "sslDebug.h" -0.230277 | #include "sslUtils.h" -0.523391 | #include "sslCrypto.h" -0.667234 | #include "sslRand.h" -0.733366 | #include "sslDigests.h" -2.141953 | -0.575445 | #include -0.179082 | #include -1.204724 | -0.914957 | #include -0.659719 | #include -1.083673 | #include -1.215132 | -1.010102 | #ifdef USE_CDSA_CRYPTO -1.709807 | //#include -0.743632 | //#include -0.700713 | #include -0.535072 | #include -2.666869 | #include "ModuleAttacher.h" -1.502249 | #else -0.406246 | #include -0.671732 | #include -2.028921 | #if APPLE_DH -4.829218 | -0.510116 | #if TARGET_OS_IPHONE -0.406525 | #include -0.739917 | #endif -0.386040 | -1.967320 | static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx); -1.614552 | static size_t SSLEncodedDHKeyParamsLen(SSLContext *ctx); -1.020681 | static OSStatus SSLEncodeDHKeyParams(SSLContext *ctx, uint8_t *charPtr); -1.606334 | -0.281427 | #endif /* APPLE_DH */ -0.076263 | #endif /* USE_CDSA_CRYPTO */ -0.058708 | -2.482139 | // MARK: - -1.912580 | // MARK: Forward Static Declarations -0.073092 | -0.615474 | #if APPLE_DH -0.599635 | #if USE_CDSA_CRYPTO -0.422291 | static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx); -0.202354 | static OSStatus SSLEncodeDHKeyParams(SSLContext *ctx, uint8_t *charPtr); -0.571903 | #endif -0.705771 | static OSStatus SSLDecodeDHKeyParams(SSLContext *ctx, uint8_t **charPtr, -0.688497 | size_t length); -0.489506 | #endif -0.234435 | static OSStatus SSLDecodeECDHKeyParams(SSLContext *ctx, uint8_t **charPtr, -0.043567 | size_t length); -0.938898 | -1.948473 | #define DH_PARAM_DUMP 0 -0.677961 | #if DH_PARAM_DUMP -3.740864 | -1.115410 | static void dumpBuf(const char *name, SSLBuffer *buf) -0.014058 | { -0.464031 | printf("%s:\n", name); -0.775793 | uint8_t *cp = buf->data; -0.711298 | uint8_t *endCp = cp + buf->length; - | -0.982585 | do { -0.989309 | unsigned i; -0.388941 | for(i=0; i<16; i++) { -0.225294 | printf("%02x ", *cp++); -0.490545 | if(cp == endCp) { -0.213869 | break; -0.001764 | } -0.011896 | } -0.339748 | if(cp == endCp) { -0.037489 | break; -0.010655 | } -0.066992 | printf("\n"); -0.220105 | } while(cp < endCp); -0.217987 | printf("\n"); -0.045284 | } -0.820898 | #else -0.331937 | #define dumpBuf(n, b) -0.425633 | #endif /* DH_PARAM_DUMP */ -0.034937 | -1.039829 | #if APPLE_DH -1.584526 | -0.736244 | // MARK: - -1.985784 | // MARK: Local Diffie-Hellman Parameter Generator -0.131393 | -1.022725 | /* -1.897087 | * Process-wide server-supplied Diffie-Hellman parameters. -3.436300 | * This might be overridden by some API_supplied parameters -0.924340 | * in the future. -0.116683 | */ -2.227506 | struct ServerDhParams -0.004622 | { -2.893156 | /* these two for sending over the wire */ -1.249049 | SSLBuffer prime; -0.226812 | SSLBuffer generator; -1.781542 | /* this one for sending to the CSP at key gen time */ -1.100281 | SSLBuffer paramBlock; -2.499370 | }; - | -0.071361 | -0.642287 | #endif /* APPLE_DH */ -0.053409 | -0.125816 | // MARK: - -0.952009 | // MARK: RSA Key Exchange -0.054985 | -0.814696 | /* -2.687892 | * Client RSA Key Exchange msgs actually start with a two-byte -2.491053 | * length field, contrary to the first version of RFC 2246, dated -1.456314 | * January 1999. See RFC 2246, March 2002, section 7.4.7.1 for -2.055357 | * updated requirements. -0.204975 | */ -1.580515 | #define RSA_CLIENT_KEY_ADD_LENGTH 1 -1.462852 | -0.791908 | static OSStatus -1.430344 | SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLPubKey *key, SSLContext *ctx) -0.003765 | { -1.848820 | #if 0 -1.704130 | SSLBuffer modulus, exponent; -0.656077 | uint8_t *charPtr; -4.690898 | -0.381717 | #ifdef USE_CDSA_CRYPTO -2.801870 | if(err = attachToCsp(ctx)) { -0.114946 | return err; -0.746461 | } - | -4.276662 | /* Note currently ALL public keys are raw, obtained from the CL... */ -0.978136 | assert((*key)->KeyHeader.BlobType == CSSM_KEYBLOB_RAW); -0.321629 | #endif /* USE_CDSA_CRYPTO */ - | -1.767821 | err = sslGetPubKeyBits(ctx, -0.430538 | key, -0.163560 | &modulus, -0.095332 | &exponent); -0.155099 | if(err) { -0.647929 | SSLFreeBuffer(&modulus); -0.006026 | SSLFreeBuffer(&exponent); -0.032639 | return err; -0.172258 | } - | -1.049418 | if ((err = SSLAllocBuffer(keyParams, -0.981417 | modulus.length + exponent.length + 4, ctx)) != 0) { -0.534072 | return err; -1.343431 | } -0.188761 | charPtr = keyParams->data; -0.957428 | charPtr = SSLEncodeInt(charPtr, modulus.length, 2); -0.054729 | memcpy(charPtr, modulus.data, modulus.length); -0.015565 | charPtr += modulus.length; -0.028468 | charPtr = SSLEncodeInt(charPtr, exponent.length, 2); -0.075908 | memcpy(charPtr, exponent.data, exponent.length); - | -1.350289 | /* these were mallocd by sslGetPubKeyBits() */ -0.051507 | SSLFreeBuffer(&modulus); -0.068479 | SSLFreeBuffer(&exponent); -1.790113 | return errSecSuccess; -0.190275 | #else -1.598717 | CFDataRef modulus = SecKeyCopyModulus(SECKEYREF(key)); -0.491329 | if (!modulus) { -0.513609 | sslErrorLog("SSLEncodeRSAKeyParams: SecKeyCopyModulus failed\n"); -0.411027 | return errSSLCrypto; -0.544432 | } -0.090480 | CFDataRef exponent = SecKeyCopyExponent(SECKEYREF(key)); -0.014496 | if (!exponent) { -0.006101 | sslErrorLog("SSLEncodeRSAKeyParams: SecKeyCopyExponent failed\n"); -0.095173 | CFRelease(modulus); -0.009322 | return errSSLCrypto; -1.058461 | } - | -0.335711 | CFIndex modulusLength = CFDataGetLength(modulus); -0.059986 | CFIndex exponentLength = CFDataGetLength(exponent); -0.643269 | sslDebugLog("SSLEncodeRSAKeyParams: modulus len=%ld, exponent len=%ld\n", -0.217055 | modulusLength, exponentLength); -1.036486 | OSStatus err; -0.327916 | if ((err = SSLAllocBuffer(keyParams, -0.456220 | modulusLength + exponentLength + 4)) != 0) { -2.485327 | CFReleaseSafe(exponent); -0.016595 | CFReleaseSafe(modulus); -0.036935 | return err; -0.439453 | } -0.073725 | uint8_t *charPtr = keyParams->data; -0.518056 | charPtr = SSLEncodeSize(charPtr, modulusLength, 2); -0.030209 | memcpy(charPtr, CFDataGetBytePtr(modulus), modulusLength); -0.003698 | charPtr += modulusLength; -0.005971 | charPtr = SSLEncodeSize(charPtr, exponentLength, 2); -0.039102 | memcpy(charPtr, CFDataGetBytePtr(exponent), exponentLength); -0.466358 | CFRelease(modulus); -0.033103 | CFRelease(exponent); -0.068027 | return errSecSuccess; -0.081483 | #endif -0.133117 | } -0.021685 | -0.213709 | static OSStatus -1.065120 | SSLEncodeRSAPremasterSecret(SSLContext *ctx) -3.131059 | { SSLBuffer randData; -0.359373 | OSStatus err; - | -0.844659 | if ((err = SSLAllocBuffer(&ctx->preMasterSecret, -0.685233 | SSL_RSA_PREMASTER_SECRET_SIZE)) != 0) -0.312887 | return err; - | -1.723739 | assert(ctx->negProtocolVersion >= SSL_Version_3_0); - | -1.236832 | SSLEncodeInt(ctx->preMasterSecret.data, ctx->clientReqProtocol, 2); -0.471085 | randData.data = ctx->preMasterSecret.data+2; -0.138330 | randData.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2; -0.640888 | if ((err = sslRand(&randData)) != 0) -0.170789 | return err; -0.179462 | return errSecSuccess; -0.082438 | } -0.011978 | -0.988037 | /* -1.810033 | * Generate a server key exchange message signed by our RSA or DSA private key. -0.559883 | */ -3.257529 | -0.159853 | static OSStatus -1.544696 | SSLSignServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgorithm sigAlg, SSLBuffer exchangeParams, SSLBuffer signature, size_t *actSigLen) -0.042549 | { -0.659393 | OSStatus err; -1.707953 | SSLBuffer hashOut, hashCtx, clientRandom, serverRandom; -0.843434 | uint8_t hashes[SSL_MAX_DIGEST_LEN]; -1.201981 | SSLBuffer signedHashes; -1.133366 | uint8_t *dataToSign; -0.306004 | size_t dataToSignLen; -2.657490 | const HashReference *hashRef; -1.139760 | SecAsn1AlgId algId; - | -1.015630 | signedHashes.data = 0; -0.614090 | hashCtx.data = 0; - | -0.415333 | clientRandom.data = ctx->clientRandom; -0.644382 | clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; -0.007688 | serverRandom.data = ctx->serverRandom; -0.057932 | serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; - | -0.396419 | switch (sigAlg.hash) { -0.741785 | case SSL_HashAlgorithmSHA1: -0.671924 | hashRef = &SSLHashSHA1; -0.562276 | algId.algorithm = CSSMOID_SHA1WithRSA; -0.058431 | break; -0.103556 | case SSL_HashAlgorithmSHA256: -0.010107 | hashRef = &SSLHashSHA256; -0.003154 | algId.algorithm = CSSMOID_SHA256WithRSA; -0.007043 | break; -0.049468 | case SSL_HashAlgorithmSHA384: -0.006880 | hashRef = &SSLHashSHA384; -0.002091 | algId.algorithm = CSSMOID_SHA384WithRSA; -0.004332 | break; -0.575645 | default: -0.538676 | sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg.hash); -0.452688 | return errSSLProtocol; -0.170669 | } - | -3.608420 | -1.095328 | dataToSign = hashes; -0.545797 | dataToSignLen = hashRef->digestSize; -0.279384 | hashOut.data = hashes; -0.067361 | hashOut.length = hashRef->digestSize; - | -0.768984 | if ((err = ReadyHash(hashRef, &hashCtx)) != 0) -1.255909 | goto fail; -0.770132 | if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0) -0.004171 | goto fail; -0.002243 | if ((err = hashRef->update(&hashCtx, &serverRandom)) != 0) -0.010008 | goto fail; -0.025707 | if ((err = hashRef->update(&hashCtx, &exchangeParams)) != 0) -0.028584 | goto fail; -0.032756 | if ((err = hashRef->final(&hashCtx, &hashOut)) != 0) -0.086682 | goto fail; - | -0.777271 | if(sigAlg.signature==SSL_SignatureAlgorithmRSA) { -1.076743 | err = sslRsaSign(ctx, -1.828033 | ctx->signingPrivKeyRef, -0.380602 | &algId, -0.290224 | dataToSign, -0.012741 | dataToSignLen, -0.142647 | signature.data, -0.260090 | signature.length, -0.037424 | actSigLen); -0.339627 | } else { -0.784511 | err = sslRawSign(ctx, -0.030479 | ctx->signingPrivKeyRef, -2.296425 | dataToSign, // one or two hashes -0.084872 | dataToSignLen, -0.072994 | signature.data, -0.022427 | signature.length, -0.027848 | actSigLen); -1.624499 | } - | -0.523387 | if(err) { -1.153399 | sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify " -0.557144 | "returned %d\n", (int)err); -0.351368 | goto fail; -0.230952 | } -0.803167 | -0.086282 | fail: -0.448639 | SSLFreeBuffer(&signedHashes); -0.076035 | SSLFreeBuffer(&hashCtx); -0.051867 | return err; -0.133084 | } -0.013037 | -0.199439 | static OSStatus -0.389493 | SSLSignServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer exchangeParams, SSLBuffer signature, size_t *actSigLen) -0.026394 | { -0.254165 | OSStatus err; -0.628122 | uint8_t hashes[SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN]; -1.267513 | SSLBuffer clientRandom,serverRandom,hashCtx, hash; -0.375225 | uint8_t *dataToSign; -0.156028 | size_t dataToSignLen; - | -0.500889 | hashCtx.data = 0; - | -3.518492 | /* cook up hash(es) for raw sign */ -0.476278 | clientRandom.data = ctx->clientRandom; -0.008251 | clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; -0.003265 | serverRandom.data = ctx->serverRandom; -0.038277 | serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; - | -0.370425 | if(isRsa) { -2.127874 | /* skip this if signing with DSA */ -0.282940 | dataToSign = hashes; -0.075328 | dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN; -0.689328 | hash.data = &hashes[0]; -0.197418 | hash.length = SSL_MD5_DIGEST_LEN; - | -0.092987 | if ((err = ReadyHash(&SSLHashMD5, &hashCtx)) != 0) -0.056544 | goto fail; -0.064455 | if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0) -0.002091 | goto fail; -0.003293 | if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0) -0.018014 | goto fail; -0.054249 | if ((err = SSLHashMD5.update(&hashCtx, &exchangeParams)) != 0) -0.006729 | goto fail; -0.003712 | if ((err = SSLHashMD5.final(&hashCtx, &hash)) != 0) -0.273510 | goto fail; -0.568719 | if ((err = SSLFreeBuffer(&hashCtx)) != 0) -0.205751 | goto fail; -1.017798 | } -0.322926 | else { -1.286728 | /* DSA - just use the SHA1 hash */ -0.197772 | dataToSign = &hashes[SSL_MD5_DIGEST_LEN]; -0.004698 | dataToSignLen = SSL_SHA1_DIGEST_LEN; -0.910342 | } -0.168993 | hash.data = &hashes[SSL_MD5_DIGEST_LEN]; -0.110157 | hash.length = SSL_SHA1_DIGEST_LEN; -0.041608 | if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) -1.589359 | goto fail; -0.004088 | if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) -0.263145 | goto fail; -0.000423 | if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) -0.006727 | goto fail; -0.001789 | if ((err = SSLHashSHA1.update(&hashCtx, &exchangeParams)) != 0) -0.007453 | goto fail; -0.002254 | if ((err = SSLHashSHA1.final(&hashCtx, &hash)) != 0) -0.065264 | goto fail; -0.011491 | if ((err = SSLFreeBuffer(&hashCtx)) != 0) -0.088307 | goto fail; - | -2.741652 | -0.527486 | err = sslRawSign(ctx, -0.052166 | ctx->signingPrivKeyRef, -0.054097 | dataToSign, // one or two hashes -0.004316 | dataToSignLen, -0.003506 | signature.data, -0.001476 | signature.length, -0.027327 | actSigLen); -0.231037 | if(err) { -0.545200 | goto fail; -0.212488 | } -0.316647 | -0.025595 | fail: -0.836509 | SSLFreeBuffer(&hashCtx); - | -0.027638 | return err; -0.114452 | } -0.014812 | -3.089514 | static -1.349797 | OSStatus FindSigAlg(SSLContext *ctx, -0.572192 | SSLSignatureAndHashAlgorithm *alg) -0.033775 | { -1.715976 | unsigned i; - | -0.816743 | assert(ctx->protocolSide == kSSLServerSide); -1.482623 | assert(ctx->negProtocolVersion >= TLS_Version_1_2); -2.611374 | assert(!ctx->isDTLS); - | -1.521052 | if((ctx->numClientSigAlgs==0) ||(ctx->clientSigAlgs==NULL)) -1.694055 | return errSSLInternal; - | -2.963185 | //FIXME: Need a better way to select here -0.281157 | for(i=0; inumClientSigAlgs; i++) { -0.768686 | alg->hash = ctx->clientSigAlgs[i].hash; -0.089575 | alg->signature = ctx->clientSigAlgs[i].signature; -3.095971 | //We only support RSA for certs on the server side - but we should test against the cert type -0.596612 | if(ctx->clientSigAlgs[i].signature != SSL_SignatureAlgorithmRSA) -0.111017 | continue; -2.141445 | //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits keys. -1.963788 | // We should actually test against what the cert can do. -0.391808 | if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) { -0.491149 | return errSecSuccess; -0.013599 | } -0.142259 | } -1.796789 | // We could not find a supported signature and hash algorithm -0.432873 | return errSSLProtocol; -0.130998 | } -0.054932 | -1.149153 | static OSStatus -2.043907 | SSLEncodeSignedServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx) -1.842006 | { OSStatus err; -1.679537 | uint8_t *charPtr; -0.998944 | size_t outputLen; -1.848198 | bool isRsa = true; -1.047179 | size_t maxSigLen; -1.564124 | size_t actSigLen; -1.243741 | SSLBuffer signature; -3.309223 | int head = 4; -2.432102 | SSLBuffer exchangeParams; - | -0.664420 | assert(ctx->protocolSide == kSSLServerSide); -1.812434 | assert(ctx->signingPubKey != NULL); -1.318016 | assert(ctx->negProtocolVersion >= SSL_Version_3_0); -1.054931 | exchangeParams.data = 0; -0.565805 | signature.data = 0; -3.554532 | -1.169638 | #if ENABLE_DTLS -0.462191 | if(ctx->negProtocolVersion == DTLS_Version_1_0) { -1.476506 | head+=8; -0.208596 | } -0.219460 | #endif - | -4.020039 | -3.152716 | /* Set up parameter block to hash ==> exchangeParams */ -1.437634 | switch(ctx->selectedCipherSpecParams.keyExchangeMethod) { -0.597066 | case SSL_RSA: -0.494212 | case SSL_RSA_EXPORT: -1.281309 | /* -2.418600 | * Parameter block = encryption public key. -3.071094 | * If app hasn't supplied a separate encryption cert, abort. -0.061389 | */ -0.415549 | if(ctx->encryptPubKey == NULL) { -1.300347 | sslErrorLog("RSAServerKeyExchange: no encrypt cert\n"); -0.845557 | return errSSLBadConfiguration; -0.045356 | } -0.836391 | err = SSLEncodeRSAKeyParams(&exchangeParams, -0.558104 | ctx->encryptPubKey, ctx); -0.199671 | break; -2.778214 | -1.406383 | #if APPLE_DH - | -0.295774 | case SSL_DHE_DSS: -0.269791 | case SSL_DHE_DSS_EXPORT: -0.426178 | isRsa = false; -1.443708 | /* and fall through */ -0.086595 | case SSL_DHE_RSA: -0.010031 | case SSL_DHE_RSA_EXPORT: -0.947766 | { -0.333598 | /* -1.046024 | * Parameter block = {prime, generator, public key} -1.767393 | * Obtain D-H parameters (if we don't have them) and a key pair. -0.108803 | */ -1.250018 | err = SSLGenServerDHParamsAndKey(ctx); -0.259413 | if(err) { -0.162691 | return err; -0.085467 | } -1.422969 | size_t len = SSLEncodedDHKeyParamsLen(ctx); -0.456903 | err = SSLAllocBuffer(&exchangeParams, len); -0.067795 | if(err) { -0.717151 | goto fail; -0.021851 | } -0.413141 | err = SSLEncodeDHKeyParams(ctx, exchangeParams.data); -0.181727 | break; -0.054684 | } -0.896602 | -0.401559 | #endif /* APPLE_DH */ - | -0.173663 | default: -1.032931 | /* shouldn't be here */ -0.341345 | assert(0); -0.213866 | return errSSLInternal; -0.302519 | } - | -1.209336 | SSLSignatureAndHashAlgorithm sigAlg; - | -4.094413 | -2.330201 | /* preallocate a buffer for signing */ -1.091816 | err = sslGetMaxSigSize(ctx->signingPrivKeyRef, &maxSigLen); -0.152078 | if(err) { -0.089274 | goto fail; -0.098576 | } -0.075120 | err = SSLAllocBuffer(&signature, maxSigLen); -0.014882 | if(err) { -0.006273 | goto fail; -0.130428 | } - | -1.265946 | outputLen = exchangeParams.length + 2; - | -2.686739 | if (sslVersionIsLikeTls12(ctx)) -0.148923 | { -1.018473 | err=FindSigAlg(ctx, &sigAlg); -0.343505 | if(err) -0.307621 | goto fail; - | -0.603618 | outputLen += 2; -1.004906 | err = SSLSignServerKeyExchangeTls12(ctx, sigAlg, exchangeParams, -0.732344 | signature, &actSigLen); -0.840894 | } else { -0.381232 | err = SSLSignServerKeyExchange(ctx, isRsa, exchangeParams, -0.353483 | signature, &actSigLen); -0.387733 | } - | -0.280294 | if(err) -0.045618 | goto fail; - | -0.351580 | assert(actSigLen <= maxSigLen); - | -0.287640 | outputLen += actSigLen; - | -2.040272 | /* package it all up */ -0.557926 | keyExch->protocolVersion = ctx->negProtocolVersion; -0.386680 | keyExch->contentType = SSL_RecordTypeHandshake; -0.902050 | if ((err = SSLAllocBuffer(&keyExch->contents, outputLen+head)) != 0) -0.218249 | goto fail; - | -1.178229 | charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, outputLen); - | -0.100573 | memcpy(charPtr, exchangeParams.data, exchangeParams.length); -0.070680 | charPtr += exchangeParams.length; - | -0.110826 | if (sslVersionIsLikeTls12(ctx)) -0.019792 | { -0.455695 | *charPtr++=sigAlg.hash; -0.003623 | *charPtr++=sigAlg.signature; -0.183455 | } - | -0.729776 | charPtr = SSLEncodeInt(charPtr, actSigLen, 2); -0.267937 | memcpy(charPtr, signature.data, actSigLen); -0.899779 | assert((charPtr + actSigLen) == -0.295290 | (keyExch->contents.data + keyExch->contents.length)); - | -0.733557 | err = errSecSuccess; -0.407972 | -0.035434 | fail: -0.260949 | SSLFreeBuffer(&exchangeParams); -0.051065 | SSLFreeBuffer(&signature); -0.046077 | return err; -0.221953 | } -0.023109 | -0.172373 | static OSStatus -0.785805 | SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, -0.926400 | uint8_t *signature, UInt16 signatureLen) -0.132728 | { -0.269496 | OSStatus err; -1.840058 | SSLBuffer hashOut, hashCtx, clientRandom, serverRandom; -0.694580 | uint8_t hashes[SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN]; -1.039667 | SSLBuffer signedHashes; -1.231391 | uint8_t *dataToSign; -0.524753 | size_t dataToSignLen; - | -0.696077 | signedHashes.data = 0; -0.448648 | hashCtx.data = 0; - | -0.313950 | clientRandom.data = ctx->clientRandom; -0.620012 | clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; -0.007327 | serverRandom.data = ctx->serverRandom; -0.041988 | serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; - | -2.973267 | -0.625055 | if(isRsa) { -2.176571 | /* skip this if signing with DSA */ -0.534754 | dataToSign = hashes; -0.104107 | dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN; -0.433531 | hashOut.data = hashes; -0.285319 | hashOut.length = SSL_MD5_DIGEST_LEN; -1.949969 | -1.026579 | if ((err = ReadyHash(&SSLHashMD5, &hashCtx)) != 0) -0.166480 | goto fail; -0.166053 | if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0) -0.002601 | goto fail; -0.003444 | if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0) -0.006668 | goto fail; -0.035897 | if ((err = SSLHashMD5.update(&hashCtx, &signedParams)) != 0) -0.012789 | goto fail; -0.018313 | if ((err = SSLHashMD5.final(&hashCtx, &hashOut)) != 0) -0.071688 | goto fail; -0.756166 | } -0.207089 | else { -1.410842 | /* DSA, ECDSA - just use the SHA1 hash */ -0.199593 | dataToSign = &hashes[SSL_MD5_DIGEST_LEN]; -0.005410 | dataToSignLen = SSL_SHA1_DIGEST_LEN; -1.377072 | } - | -0.541137 | hashOut.data = hashes + SSL_MD5_DIGEST_LEN; -0.184799 | hashOut.length = SSL_SHA1_DIGEST_LEN; -0.740362 | if ((err = SSLFreeBuffer(&hashCtx)) != 0) -0.213254 | goto fail; - | -0.065284 | if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) -0.038564 | goto fail; -0.010991 | if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) -0.003487 | goto fail; -0.001015 | if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) -0.006397 | goto fail; -0.002107 | if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) -0.009297 | goto fail; -3.545460 | goto fail; -0.009888 | if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) -0.049823 | goto fail; - | -1.554807 | err = sslRawVerify(ctx, -1.248239 | ctx->peerPubKey, -1.343035 | dataToSign, /* plaintext */ -0.154980 | dataToSignLen, /* plaintext length */ -0.554053 | signature, -0.279519 | signatureLen); -0.631927 | if(err) { -0.747847 | sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify " -0.419512 | "returned %d\n", (int)err); -0.169207 | goto fail; -0.245341 | } -0.966499 | -0.087338 | fail: -0.257618 | SSLFreeBuffer(&signedHashes); -0.110737 | SSLFreeBuffer(&hashCtx); -0.048938 | return err; -3.392478 | -0.097468 | } -0.040155 | -0.118132 | static OSStatus -0.276560 | SSLVerifySignedServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgorithm sigAlg, SSLBuffer signedParams, -0.097054 | uint8_t *signature, UInt16 signatureLen) -0.024606 | { -0.060830 | OSStatus err; -0.030496 | SSLBuffer hashOut, hashCtx, clientRandom, serverRandom; -0.445523 | uint8_t hashes[SSL_MAX_DIGEST_LEN]; -0.017514 | SSLBuffer signedHashes; -0.019925 | uint8_t *dataToSign; -0.141139 | size_t dataToSignLen; -2.512928 | const HashReference *hashRef; -1.344521 | SecAsn1AlgId algId; - | -0.057826 | signedHashes.data = 0; -0.013924 | hashCtx.data = 0; - | -0.015907 | clientRandom.data = ctx->clientRandom; -0.000846 | clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; -0.000253 | serverRandom.data = ctx->serverRandom; -0.004891 | serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE; - | -0.528476 | switch (sigAlg.hash) { -0.071624 | case SSL_HashAlgorithmSHA1: -0.080479 | hashRef = &SSLHashSHA1; -0.577517 | algId.algorithm = CSSMOID_SHA1WithRSA; -0.075270 | break; -0.023419 | case SSL_HashAlgorithmSHA256: -0.006788 | hashRef = &SSLHashSHA256; -0.002881 | algId.algorithm = CSSMOID_SHA256WithRSA; -0.006390 | break; -0.177930 | case SSL_HashAlgorithmSHA384: -0.011873 | hashRef = &SSLHashSHA384; -0.004759 | algId.algorithm = CSSMOID_SHA384WithRSA; -0.006379 | break; -0.127807 | default: -0.245273 | sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg.hash); -0.216918 | return errSSLProtocol; -0.130959 | } - | -2.731077 | -0.339127 | dataToSign = hashes; -0.241820 | dataToSignLen = hashRef->digestSize; -0.072237 | hashOut.data = hashes; -0.029090 | hashOut.length = hashRef->digestSize; - | -0.051369 | if ((err = ReadyHash(hashRef, &hashCtx)) != 0) -0.046369 | goto fail; -0.045045 | if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0) -0.001666 | goto fail; -0.000584 | if ((err = hashRef->update(&hashCtx, &serverRandom)) != 0) -0.003078 | goto fail; -0.002122 | if ((err = hashRef->update(&hashCtx, &signedParams)) != 0) -0.013515 | goto fail; -0.014617 | if ((err = hashRef->final(&hashCtx, &hashOut)) != 0) -0.023493 | goto fail; - | -0.498213 | if(sigAlg.signature==SSL_SignatureAlgorithmRSA) { -0.724687 | err = sslRsaVerify(ctx, -0.100473 | ctx->peerPubKey, -0.443601 | &algId, -0.274310 | dataToSign, -0.008081 | dataToSignLen, -0.030243 | signature, -0.036439 | signatureLen); -0.328212 | } else { -0.324023 | err = sslRawVerify(ctx, -0.022149 | ctx->peerPubKey, -0.062828 | dataToSign, /* plaintext */ -0.000930 | dataToSignLen, /* plaintext length */ -0.001355 | signature, -0.003364 | signatureLen); -1.589880 | } - | -0.162268 | if(err) { -0.215608 | sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify " -0.023090 | "returned %d\n", (int)err); -0.073695 | goto fail; -0.103626 | } -0.086783 | -0.005050 | fail: -0.009061 | SSLFreeBuffer(&signedHashes); -0.003143 | SSLFreeBuffer(&hashCtx); -0.003337 | return err; -0.818522 | -0.118370 | } -0.025358 | -1.618969 | /* -1.731693 | * Decode and verify a server key exchange message signed by server's -0.749418 | * public key. -0.350350 | */ -0.197743 | static OSStatus -0.568904 | SSLDecodeSignedServerKeyExchange(SSLBuffer message, SSLContext *ctx) -0.099788 | { -0.703979 | OSStatus err; -1.431250 | UInt16 modulusLen = 0, exponentLen = 0, signatureLen; -0.475737 | uint8_t *modulus = NULL, *exponent = NULL, *signature; -0.423080 | bool isRsa = true; - | -0.570518 | assert(ctx->protocolSide == kSSLClientSide); - | -0.655670 | if (message.length < 2) { -1.039649 | sslErrorLog("SSLDecodeSignedServerKeyExchange: msg len error 1\n"); -0.133132 | return errSSLProtocol; -0.137656 | } - | -2.035907 | /* first extract the key-exchange-method-specific parameters */ -0.772431 | uint8_t *charPtr = message.data; -1.027356 | uint8_t *endCp = charPtr + message.length; -0.209914 | switch(ctx->selectedCipherSpecParams.keyExchangeMethod) { -0.032559 | case SSL_RSA: -0.025093 | case SSL_RSA_EXPORT: -0.403136 | modulusLen = SSLDecodeInt(charPtr, 2); -0.148816 | charPtr += 2; -0.273504 | if((charPtr + modulusLen) > endCp) { -0.772093 | sslErrorLog("signedServerKeyExchange: msg len error 2\n"); -0.046518 | return errSSLProtocol; -0.010398 | } -0.049454 | modulus = charPtr; -0.153081 | charPtr += modulusLen; - | -0.039654 | exponentLen = SSLDecodeInt(charPtr, 2); -0.006206 | charPtr += 2; -0.006442 | if((charPtr + exponentLen) > endCp) { -0.004084 | sslErrorLog("signedServerKeyExchange: msg len error 3\n"); -0.003484 | return errSSLProtocol; -0.003666 | } -0.004016 | exponent = charPtr; -0.105581 | charPtr += exponentLen; -0.158762 | break; -0.372587 | #if APPLE_DH -0.034995 | case SSL_DHE_DSS: -0.009283 | case SSL_DHE_DSS_EXPORT: -0.034300 | isRsa = false; -0.024416 | /* and fall through */ -0.000958 | case SSL_DHE_RSA: -0.002831 | case SSL_DHE_RSA_EXPORT: -0.773230 | err = SSLDecodeDHKeyParams(ctx, &charPtr, message.length); -0.134456 | if(err) { -0.133594 | return err; -0.007434 | } -0.147659 | break; -1.414311 | #endif /* APPLE_DH */ - | -0.513676 | case SSL_ECDHE_ECDSA: -0.479980 | isRsa = false; -0.072015 | /* and fall through */ -0.044907 | case SSL_ECDHE_RSA: -0.074180 | err = SSLDecodeECDHKeyParams(ctx, &charPtr, message.length); -0.008780 | if(err) { -0.003368 | return err; -0.002857 | } -1.330403 | break; -0.756555 | default: -0.709219 | assert(0); -2.077889 | return errSSLInternal; -0.506359 | } - | -3.059641 | /* this is what's hashed */ -2.438856 | SSLBuffer signedParams; -0.885557 | signedParams.data = message.data; -1.134630 | signedParams.length = charPtr - message.data; - | -1.627683 | SSLSignatureAndHashAlgorithm sigAlg; - | -2.551218 | if (sslVersionIsLikeTls12(ctx)) { -2.195066 | /* Parse the algorithm field added in TLS1.2 */ -1.701615 | if((charPtr + 2) > endCp) { -2.974386 | sslErrorLog("signedServerKeyExchange: msg len error 499\n"); -0.114085 | return errSSLProtocol; -0.103492 | } -0.345516 | sigAlg.hash = *charPtr++; -0.086964 | sigAlg.signature = *charPtr++; -0.912678 | } - | -1.670928 | signatureLen = SSLDecodeInt(charPtr, 2); -0.217290 | charPtr += 2; -0.397842 | if((charPtr + signatureLen) != endCp) { -0.428876 | sslErrorLog("signedServerKeyExchange: msg len error 4\n"); -0.007159 | return errSSLProtocol; -0.308155 | } -0.381228 | signature = charPtr; - | -0.572927 | if (sslVersionIsLikeTls12(ctx)) -0.338126 | { -0.765410 | err = SSLVerifySignedServerKeyExchangeTls12(ctx, sigAlg, signedParams, -0.204096 | signature, signatureLen); -0.503610 | } else { -0.509369 | err = SSLVerifySignedServerKeyExchange(ctx, isRsa, signedParams, -0.022302 | signature, signatureLen); -0.238306 | } - | -1.159039 | if(err) -1.629767 | goto fail; - | -2.698741 | /* Signature matches; now replace server key with new key (RSA only) */ -1.395475 | switch(ctx->selectedCipherSpecParams.keyExchangeMethod) { -0.651418 | case SSL_RSA: -0.557686 | case SSL_RSA_EXPORT: -0.923543 | { -0.975641 | SSLBuffer modBuf; -0.263724 | SSLBuffer expBuf; - | -2.692253 | /* first free existing peerKey */ -2.333766 | sslFreePubKey(&ctx->peerPubKey); /* no KCItem */ - | -2.102952 | /* and cook up a new one from raw bits */ -0.275609 | modBuf.data = modulus; -0.115799 | modBuf.length = modulusLen; -0.039099 | expBuf.data = exponent; -0.037665 | expBuf.length = exponentLen; -0.975361 | err = sslGetPubKeyFromBits(ctx, -0.712322 | &modBuf, -0.028624 | &expBuf, -0.164943 | &ctx->peerPubKey); -0.271891 | break; -0.042437 | } -0.233082 | case SSL_DHE_RSA: -0.459589 | case SSL_DHE_RSA_EXPORT: -0.204170 | case SSL_DHE_DSS: -0.006303 | case SSL_DHE_DSS_EXPORT: -0.624003 | case SSL_ECDHE_ECDSA: -0.091865 | case SSL_ECDHE_RSA: -1.119088 | break; /* handled above */ -0.106214 | default: -0.044212 | assert(0); -1.412971 | } -1.092339 | fail: -0.643536 | return err; -0.290244 | } -0.087551 | -0.586328 | static OSStatus -1.277069 | SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx) -1.580978 | { OSStatus err; -2.807170 | size_t outputLen, localKeyModulusLen; -1.620469 | SSLProtocolVersion version; -1.610137 | Boolean useEncryptKey = false; -1.288503 | uint8_t *src = NULL; -1.308688 | SSLPrivKey *keyRef = NULL; - | -0.851743 | assert(ctx->protocolSide == kSSLServerSide); -1.636212 | if (ctx->encryptPrivKeyRef) { -0.363213 | useEncryptKey = true; -1.506930 | } -0.421438 | if (useEncryptKey) { -0.442697 | keyRef = ctx->encryptPrivKeyRef; -3.929345 | /* FIXME: when 3420180 is implemented, pick appropriate creds here */ -0.956169 | } -0.226492 | else { -0.420360 | keyRef = ctx->signingPrivKeyRef; -0.037603 | /* FIXME: when 3420180 is implemented, pick appropriate creds here */ -0.224587 | } - | -1.064355 | localKeyModulusLen = sslPrivKeyLengthInBytes(keyRef); -0.312580 | if (localKeyModulusLen == 0) { -0.461441 | sslErrorLog("SSLDecodeRSAKeyExchange: private key modulus is 0\n"); -0.380146 | return errSSLCrypto; -0.190016 | } - | -1.316000 | /* -2.474008 | * We have to tolerate incoming key exchange msgs with and without the -1.811249 | * two-byte "encrypted length" field. -0.173147 | */ -0.520171 | if (keyExchange.length == localKeyModulusLen) { -1.565858 | /* no length encoded */ -0.098434 | src = keyExchange.data; -0.665863 | } -0.429175 | else if((keyExchange.length == (localKeyModulusLen + 2)) && -1.805672 | (ctx->negProtocolVersion >= TLS_Version_1_0)) { -1.958062 | /* TLS only - skip the length bytes */ -0.037503 | src = keyExchange.data + 2; -0.064031 | } -0.063749 | else { -0.941644 | sslErrorLog("SSLDecodeRSAKeyExchange: length error (exp %u got %u)\n", -0.135900 | (unsigned)localKeyModulusLen, (unsigned)keyExchange.length); -0.371286 | return errSSLProtocol; -0.755124 | } -1.175015 | err = SSLAllocBuffer(&ctx->preMasterSecret, SSL_RSA_PREMASTER_SECRET_SIZE); -0.916528 | if(err != 0) { -0.534568 | return err; -0.469802 | } - | -0.990472 | /* -1.705435 | * From this point on, to defend against the Bleichenbacher attack -1.955766 | * and its Klima-Pokorny-Rosa variant, any errors we detect are *not* -1.927738 | * reported to the caller or the peer. If we detect any error during -1.913780 | * decryption (e.g., bad PKCS1 padding) or in the testing of the version -1.496446 | * number in the premaster secret, we proceed by generating a random -1.691968 | * premaster secret, with the correct version number, and tell our caller -1.802832 | * that everything is fine. This session will fail as soon as the -1.621064 | * finished messages are sent, since we will be using a bogus premaster -2.539498 | * secret (and hence bogus session and MAC keys). Meanwhile we have -2.557244 | * not provided any side channel information relating to the cause of -0.473930 | * the failure. -0.441499 | * -0.810296 | * See http://eprint.iacr.org/2003/052/ for more info. -0.299766 | */ -0.855508 | err = sslRsaDecrypt(ctx, -0.337740 | keyRef, -1.419545 | #if USE_CDSA_CRYPTO -0.699919 | CSSM_PADDING_PKCS1, -0.148990 | #else -0.293037 | kSecPaddingPKCS1, -0.012721 | #endif -0.173802 | src, -0.981444 | localKeyModulusLen, // ciphertext len -0.136584 | ctx->preMasterSecret.data, -0.749210 | SSL_RSA_PREMASTER_SECRET_SIZE, // plaintext buf available -0.353456 | &outputLen); - | -0.535366 | if(err != errSecSuccess) { -1.013591 | /* possible Bleichenbacher attack */ -1.379227 | sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: RSA decrypt fail"); -1.003212 | } -0.105871 | else if(outputLen != SSL_RSA_PREMASTER_SECRET_SIZE) { -0.497341 | sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: premaster secret size error"); -1.408627 | err = errSSLProtocol; // not passed back to caller -1.696166 | } - | -0.236050 | if(err == errSecSuccess) { -0.539619 | /* -2.929189 | * Two legal values here - the one we actually negotiated (which is -1.815486 | * technically incorrect but not uncommon), and the one the client -1.769347 | * sent as its preferred version in the client hello msg. -0.091553 | */ -0.272001 | version = (SSLProtocolVersion)SSLDecodeInt(ctx->preMasterSecret.data, 2); -0.308307 | if((version != ctx->negProtocolVersion) && -0.760348 | (version != ctx->clientReqProtocol)) { -0.638729 | /* possible Klima-Pokorny-Rosa attack */ -0.122014 | sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: version error"); -0.261424 | err = errSSLProtocol; -0.069918 | } -1.579016 | } -0.225921 | if(err != errSecSuccess) { -0.516435 | /* -2.120391 | * Obfuscate failures for defense against Bleichenbacher and -0.102806 | * Klima-Pokorny-Rosa attacks. -0.017985 | */ -0.598868 | SSLEncodeInt(ctx->preMasterSecret.data, ctx->negProtocolVersion, 2); -1.433684 | SSLBuffer tmpBuf; -0.340336 | tmpBuf.data = ctx->preMasterSecret.data + 2; -0.015542 | tmpBuf.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2; -2.498598 | /* must ignore failures here */ -1.065260 | sslRand(&tmpBuf); -0.413362 | } - | -2.353769 | /* in any case, save premaster secret (good or bogus) and proceed */ -1.212212 | return errSecSuccess; -0.061085 | } -0.014573 | -0.147533 | static OSStatus -0.900303 | SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx) -0.216484 | { OSStatus err; -0.517066 | size_t outputLen, peerKeyModulusLen; -0.791350 | size_t bufLen; -0.314873 | uint8_t *dst; -1.078666 | bool encodeLen = false; -1.389559 | uint8_t *p; -3.231981 | int head; -1.058558 | size_t msglen; - | -0.345275 | assert(ctx->protocolSide == kSSLClientSide); -1.483620 | if ((err = SSLEncodeRSAPremasterSecret(ctx)) != 0) -0.147982 | return err; - | -1.094798 | keyExchange->contentType = SSL_RecordTypeHandshake; -0.714750 | assert(ctx->negProtocolVersion >= SSL_Version_3_0); -0.416450 | keyExchange->protocolVersion = ctx->negProtocolVersion; - | -0.261551 | peerKeyModulusLen = sslPubKeyLengthInBytes(ctx->peerPubKey); -0.234065 | if (peerKeyModulusLen == 0) { -0.101746 | sslErrorLog("SSLEncodeRSAKeyExchange: peer key modulus is 0\n"); -2.454824 | /* FIXME: we don't return an error here... is this condition ever expected? */ -0.554589 | } -1.714235 | #if SSL_DEBUG -0.533459 | sslDebugLog("SSLEncodeRSAKeyExchange: peer key modulus length = %lu\n", peerKeyModulusLen); -0.323237 | #endif -0.492864 | msglen = peerKeyModulusLen; -2.640224 | #if RSA_CLIENT_KEY_ADD_LENGTH -0.366605 | if(ctx->negProtocolVersion >= TLS_Version_1_0) { -0.589827 | msglen += 2; -0.243316 | encodeLen = true; -0.096925 | } -0.253999 | #endif -1.497825 | head = SSLHandshakeHeaderSize(keyExchange); -0.312658 | bufLen = msglen + head; -0.952513 | if ((err = SSLAllocBuffer(&keyExchange->contents, -0.575401 | bufLen)) != 0) -1.905965 | { -0.114308 | return err; -0.102561 | } -0.241547 | dst = keyExchange->contents.data + head; -0.228415 | if(encodeLen) { -1.071746 | dst += 2; -1.007183 | } - | -1.759292 | /* FIXME: can this line be removed? */ -0.592715 | p = keyExchange->contents.data; - | -1.263929 | p = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, msglen); - | -0.259632 | if(encodeLen) { -1.532776 | /* the length of the encrypted pre_master_secret */ -1.017930 | SSLEncodeSize(keyExchange->contents.data + head, -0.271375 | peerKeyModulusLen, 2); -0.331980 | } -0.364326 | err = sslRsaEncrypt(ctx, -0.126326 | ctx->peerPubKey, -0.017372 | #if USE_CDSA_CRYPTO -0.003604 | CSSM_PADDING_PKCS1, -0.002523 | #else -0.002104 | kSecPaddingPKCS1, -0.003732 | #endif -0.038588 | ctx->preMasterSecret.data, -0.076309 | SSL_RSA_PREMASTER_SECRET_SIZE, -0.082189 | dst, -0.333595 | peerKeyModulusLen, -0.145641 | &outputLen); -0.379938 | if(err) { -0.310638 | sslErrorLog("SSLEncodeRSAKeyExchange: error %d\n", (int)err); -0.144150 | return err; -0.513694 | } - | -1.062909 | assert(outputLen == (encodeLen ? msglen - 2 : msglen)); - | -0.238558 | return errSecSuccess; -1.163250 | } - | -0.027184 | -1.441130 | #if APPLE_DH -1.414702 | -2.627837 | // MARK: - -0.339435 | // MARK: Diffie-Hellman Key Exchange -0.086677 | -1.051421 | /* -1.932390 | * Diffie-Hellman setup, server side. On successful return, the -1.956765 | * following SSLContext members are valid: -0.476731 | * -2.768263 | * dhParamsPrime -0.056039 | * dhParamsGenerator -1.253886 | * dhPrivate -1.428495 | * dhExchangePublic -0.686226 | */ -0.150973 | static OSStatus -1.711154 | SSLGenServerDHParamsAndKey( -0.448915 | SSLContext *ctx) -0.356042 | { -1.283093 | OSStatus ortn; -0.553480 | assert(ctx->protocolSide == kSSLServerSide); - | -4.564260 | -0.871919 | /* -1.500509 | * Obtain D-H parameters if we don't have them. -0.132252 | */ -0.929090 | if(ctx->dhParamsEncoded.data == NULL) { -2.081538 | /* TODO: Pick appropriate group based on cipher suite */ -1.617145 | ccdh_const_gp_t gp = ccdh_gp_rfc5114_MODP_2048_256(); -0.896631 | cc_size n = ccdh_gp_n(gp); -0.873540 | size_t s = ccdh_gp_prime_size(gp); -0.661829 | uint8_t p[s]; -0.231207 | uint8_t g[s]; - | -0.896408 | ccn_write_uint(n, ccdh_gp_prime(gp), s, p); -0.200978 | ccn_write_uint(n, ccdh_gp_g(gp), s, g); - | -2.643869 | const SSLBuffer prime = { -0.227997 | .data = p, -0.229874 | .length = s, -0.274638 | }; -0.038734 | const SSLBuffer generator = { -0.001341 | .data = g, -0.005216 | .length = s, -0.125754 | }; - | -1.954410 | ortn=sslEncodeDhParams(&ctx->dhParamsEncoded, /* data mallocd and RETURNED PKCS-3 encoded */ -2.038845 | &prime, /* Wire format */ -0.812414 | &generator); /* Wire format */ - | -0.371182 | if(ortn) -0.147755 | return ortn; -0.590957 | } -2.643862 | -0.300175 | #if USE_CDSA_CRYPTO -1.561566 | /* generate per-session D-H key pair */ -2.170913 | sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL); -0.647023 | SSLFreeBuffer(&ctx->dhExchangePublic); -0.689112 | ctx->dhPrivate = (CSSM_KEY *)sslMalloc(sizeof(CSSM_KEY)); -2.053464 | CSSM_KEY pubKey; -0.702849 | ortn = sslDhGenerateKeyPair(ctx, -0.278819 | &ctx->dhParamsEncoded, -0.985734 | ctx->dhParamsPrime.length * 8, -0.519004 | &pubKey, ctx->dhPrivate); -0.172558 | if(ortn) { -0.226064 | return ortn; -0.110935 | } -1.464692 | CSSM_TO_SSLBUF(&pubKey.KeyData, &ctx->dhExchangePublic); -0.309633 | #else -2.268881 | if (!ctx->secDHContext) { -1.098330 | ortn = sslDhCreateKey(ctx); -0.284798 | if(ortn) -0.015448 | return ortn; -0.170445 | } -0.769980 | return sslDhGenerateKeyPair(ctx); -0.173404 | #endif -0.723908 | return errSecSuccess; -0.130608 | } -0.027396 | -0.523105 | /* -2.735272 | * size of DH param and public key, in wire format -0.085143 | */ -0.284252 | static size_t -1.030943 | SSLEncodedDHKeyParamsLen(SSLContext *ctx) -0.028584 | { -1.943352 | SSLBuffer prime; -0.292418 | SSLBuffer generator; - | -0.257271 | sslDecodeDhParams(&ctx->dhParamsEncoded, &prime, &generator); - | -0.794041 | return (2+prime.length+2+generator.length+2+ctx->dhExchangePublic.length); -0.058471 | } -0.009853 | -0.282681 | /* -1.180274 | * Encode DH params and public key, in wire format, in caller-supplied buffer. -0.460126 | */ -0.100224 | static OSStatus -0.388552 | SSLEncodeDHKeyParams( -0.121332 | SSLContext *ctx, -1.297304 | uint8_t *charPtr) -0.094261 | { -0.386987 | assert(ctx->protocolSide == kSSLServerSide); -0.561551 | assert(ctx->dhParamsEncoded.data != NULL); -0.227650 | assert(ctx->dhExchangePublic.data != NULL); - | -0.416201 | SSLBuffer prime; -0.039233 | SSLBuffer generator; - | -0.008446 | sslDecodeDhParams(&ctx->dhParamsEncoded, &prime, &generator); - | -0.311916 | charPtr = SSLEncodeInt(charPtr, prime.length, 2); -0.147779 | memcpy(charPtr, prime.data, prime.length); -0.085551 | charPtr += prime.length; - | -0.004205 | charPtr = SSLEncodeInt(charPtr, generator.length, 2); -0.662111 | memcpy(charPtr, generator.data, -0.046461 | generator.length); -0.003806 | charPtr += generator.length; - | -3.215649 | /* TODO: hum.... sounds like this one should be in the SecDHContext */ -0.036333 | charPtr = SSLEncodeInt(charPtr, ctx->dhExchangePublic.length, 2); -0.019864 | memcpy(charPtr, ctx->dhExchangePublic.data, -2.218534 | ctx->dhExchangePublic.length); - | -3.902678 | dumpBuf("server prime", &prime); -0.210104 | dumpBuf("server generator", &generator); -1.403706 | dumpBuf("server pub key", &ctx->dhExchangePublic); - | -1.768100 | return errSecSuccess; -0.108561 | } -0.017272 | -1.157271 | /* -2.238294 | * Decode DH params and server public key. -0.252559 | */ -0.626345 | static OSStatus -1.981436 | SSLDecodeDHKeyParams( -0.763605 | SSLContext *ctx, -1.671103 | uint8_t **charPtr, // IN/OUT -0.726358 | size_t length) -0.004919 | { -0.847415 | OSStatus err = errSecSuccess; -1.910165 | SSLBuffer prime; -0.360855 | SSLBuffer generator; - | -0.893866 | assert(ctx->protocolSide == kSSLClientSide); -1.689635 | uint8_t *endCp = *charPtr + length; - | -4.350561 | /* Allow reuse via renegotiation */ -0.956506 | SSLFreeBuffer(&ctx->dhPeerPublic); -2.110779 | -2.098181 | /* Prime, with a two-byte length */ -1.364605 | UInt32 len = SSLDecodeInt(*charPtr, 2); -0.475529 | (*charPtr) += 2; -0.533528 | if((*charPtr + len) > endCp) { -0.261581 | return errSSLProtocol; -0.762168 | } - | -0.184122 | prime.data = *charPtr; -0.899703 | prime.length = len; - | -0.138157 | (*charPtr) += len; - | -0.070024 | /* Generator, with a two-byte length */ -0.016117 | len = SSLDecodeInt(*charPtr, 2); -0.017271 | (*charPtr) += 2; -0.004752 | if((*charPtr + len) > endCp) { -0.015335 | return errSSLProtocol; -0.052474 | } - | -0.301773 | generator.data = *charPtr; -0.024996 | generator.length = len; - | -0.280203 | (*charPtr) += len; - | -1.041714 | sslEncodeDhParams(&ctx->dhParamsEncoded, &prime, &generator); - | -0.563610 | /* peer public key, with a two-byte length */ -0.021383 | len = SSLDecodeInt(*charPtr, 2); -0.020653 | (*charPtr) += 2; -0.601071 | err = SSLAllocBuffer(&ctx->dhPeerPublic, len); -0.230672 | if(err) { -0.057606 | return err; -0.123769 | } -0.158923 | memmove(ctx->dhPeerPublic.data, *charPtr, len); -0.087909 | (*charPtr) += len; - | -0.669066 | dumpBuf("client peer pub", &ctx->dhPeerPublic); -1.278386 | // dumpBuf("client prime", &ctx->dhParamsPrime); -0.453483 | // dumpBuf("client generator", &ctx->dhParamsGenerator); - | -0.150529 | return err; -0.084515 | } -0.031359 | -0.199529 | /* -1.456157 | * Given the server's Diffie-Hellman parameters, generate our -1.616499 | * own DH key pair, and perform key exchange using the server's -1.222758 | * public key and our private key. The result is the premaster -0.319503 | * secret. -1.048198 | * -3.368968 | * SSLContext members valid on entry: -0.954856 | * dhParamsPrime -0.013750 | * dhParamsGenerator -0.114007 | * dhPeerPublic -0.404579 | * -0.804799 | * SSLContext members valid on successful return: -0.764967 | * dhPrivate -0.331285 | * dhExchangePublic -0.573986 | * preMasterSecret -0.335511 | */ -0.035758 | static OSStatus -1.193329 | SSLGenClientDHKeyAndExchange(SSLContext *ctx) -0.004992 | { -2.308531 | OSStatus ortn; -5.871865 | -1.277135 | #if USE_CDSA_CRYPTO - | -0.963702 | if((ctx->dhParamsPrime.data == NULL) || -0.058976 | (ctx->dhParamsGenerator.data == NULL) || -0.037590 | (ctx->dhPeerPublic.data == NULL)) { -1.252401 | sslErrorLog("SSLGenClientDHKeyAndExchange: incomplete server params\n"); -0.139435 | return errSSLProtocol; -0.166091 | } - | -2.650145 | /* generate two keys */ -1.720243 | CSSM_KEY pubKey; -0.747393 | ctx->dhPrivate = (CSSM_KEY *)sslMalloc(sizeof(CSSM_KEY)); -1.533238 | ortn = sslDhGenKeyPairClient(ctx, -0.377298 | &ctx->dhParamsPrime, -0.015891 | &ctx->dhParamsGenerator, -0.508511 | &pubKey, ctx->dhPrivate); -0.059137 | if(ortn) { -0.461876 | sslFree(ctx->dhPrivate); -0.073045 | ctx->dhPrivate = NULL; -0.068985 | return ortn; -0.184988 | } - | -2.492589 | /* do the exchange, size of prime */ -0.550272 | ortn = sslDhKeyExchange(ctx, ctx->dhParamsPrime.length * 8, -1.122709 | &ctx->preMasterSecret); -0.025570 | if(ortn) { -0.269303 | return ortn; -0.471017 | } -1.620361 | CSSM_TO_SSLBUF(&pubKey.KeyData, &ctx->dhExchangePublic); -1.216921 | #else -1.404013 | ortn=errSSLProtocol; -1.632509 | require(ctx->dhParamsEncoded.data, out); -0.840601 | require_noerr(ortn = sslDhCreateKey(ctx), out); -0.255374 | require_noerr(ortn = sslDhGenerateKeyPair(ctx), out); -0.129736 | require_noerr(ortn = sslDhKeyExchange(ctx), out); -0.777683 | out: -0.900106 | #endif -0.198605 | return ortn; -0.908529 | } - | -0.037695 | -0.593736 | static OSStatus -2.016102 | SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx) -0.006391 | { -0.368682 | OSStatus ortn = errSecSuccess; -3.246470 | int head; - | -1.415593 | assert(ctx->negProtocolVersion >= SSL_Version_3_0); -0.237416 | assert(ctx->protocolSide == kSSLServerSide); - | -1.165721 | /* -1.765244 | * Obtain D-H parameters (if we don't have them) and a key pair. -0.143893 | */ -0.671857 | ortn = SSLGenServerDHParamsAndKey(ctx); -0.075984 | if(ortn) { -0.096855 | return ortn; -0.111203 | } - | -1.639399 | size_t length = SSLEncodedDHKeyParamsLen(ctx); - | -0.665466 | keyExch->protocolVersion = ctx->negProtocolVersion; -0.696699 | keyExch->contentType = SSL_RecordTypeHandshake; -1.519382 | head = SSLHandshakeHeaderSize(keyExch); -1.189938 | if ((ortn = SSLAllocBuffer(&keyExch->contents, length+head))) -0.182086 | return ortn; - | -1.214544 | uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, length); - | -1.440357 | /* encode prime, generator, our public key */ -0.834747 | return SSLEncodeDHKeyParams(ctx, charPtr); -0.204676 | } -0.015335 | -0.167880 | static OSStatus -0.685062 | SSLDecodeDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx) -0.006616 | { -0.460898 | OSStatus err = errSecSuccess; - | -0.348435 | assert(ctx->protocolSide == kSSLClientSide); -0.989447 | if (message.length < 6) { -0.943970 | sslErrorLog("SSLDecodeDHanonServerKeyExchange error: msg len %u\n", -0.180016 | (unsigned)message.length); -0.168064 | return errSSLProtocol; -0.327082 | } -0.306116 | uint8_t *charPtr = message.data; -0.197602 | err = SSLDecodeDHKeyParams(ctx, &charPtr, message.length); -0.382551 | if(err == errSecSuccess) { -0.650257 | if((message.data + message.length) != charPtr) { -0.434422 | err = errSSLProtocol; -0.082784 | } -0.091579 | } -0.066768 | return err; -0.168257 | } -0.034187 | -0.237313 | static OSStatus -0.893421 | SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx) -0.003538 | { -0.376954 | OSStatus ortn = errSecSuccess; -2.162528 | unsigned int publicLen; - | -0.093014 | assert(ctx->protocolSide == kSSLServerSide); -0.549878 | if(ctx->dhParamsEncoded.data == NULL) { -1.021051 | /* should never happen */ -0.558822 | assert(0); -0.380110 | return errSSLInternal; -0.240378 | } - | -1.840787 | /* this message simply contains the client's public DH key */ -0.334599 | uint8_t *charPtr = keyExchange.data; -0.220908 | publicLen = SSLDecodeInt(charPtr, 2); -0.257194 | charPtr += 2; -2.526228 | /* TODO : Check the len here ? Will fail in sslDhKeyExchange anyway */ -1.787065 | /* -0.657645 | if((keyExchange.length != publicLen + 2) || -0.423811 | (publicLen > ctx->dhParamsPrime.length)) { -0.487419 | return errSSLProtocol; -0.243792 | } -0.176015 | */ -0.745947 | SSLFreeBuffer(&ctx->dhPeerPublic); // allow reuse via renegotiation -0.207735 | ortn = SSLAllocBuffer(&ctx->dhPeerPublic, publicLen); -0.051437 | if(ortn) { -0.020357 | return ortn; -0.019276 | } -0.076759 | memmove(ctx->dhPeerPublic.data, charPtr, publicLen); - | -2.505024 | /* DH Key exchange, result --> premaster secret */ -0.578168 | SSLFreeBuffer(&ctx->preMasterSecret); -0.427151 | #if USE_CDSA_CRYPTO -0.075006 | ortn = sslDhKeyExchange(ctx, ctx->dhParamsPrime.length * 8, -0.008980 | &ctx->preMasterSecret); -0.165138 | #else -0.434582 | ortn = sslDhKeyExchange(ctx); -0.077551 | #endif -0.374081 | dumpBuf("server peer pub", &ctx->dhPeerPublic); -0.167930 | dumpBuf("server premaster", &ctx->preMasterSecret); -0.101086 | return ortn; -0.118317 | } -0.024059 | -0.171931 | static OSStatus -0.097775 | SSLEncodeDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx) -2.202916 | { OSStatus err; -1.185825 | size_t outputLen; -0.537861 | int head; - | -0.116677 | assert(ctx->protocolSide == kSSLClientSide); -0.124202 | assert(ctx->negProtocolVersion >= SSL_Version_3_0); - | -0.571026 | keyExchange->contentType = SSL_RecordTypeHandshake; -0.138940 | keyExchange->protocolVersion = ctx->negProtocolVersion; - | -0.922339 | if ((err = SSLGenClientDHKeyAndExchange(ctx)) != 0) -0.172661 | return err; - | -0.279903 | outputLen = ctx->dhExchangePublic.length + 2; -0.155293 | head = SSLHandshakeHeaderSize(keyExchange); -0.331586 | if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head))) -0.065020 | return err; - | -0.067992 | uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen); - | -0.587290 | charPtr = SSLEncodeSize(charPtr, ctx->dhExchangePublic.length, 2); -0.212736 | memcpy(charPtr, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length); - | -0.304651 | dumpBuf("client pub key", &ctx->dhExchangePublic); -0.117723 | dumpBuf("client premaster", &ctx->preMasterSecret); - | -0.503683 | return errSecSuccess; -0.136960 | } -0.029530 | -1.458043 | #endif /* APPLE_DH */ -0.097582 | -2.191375 | // MARK: - -1.115519 | // MARK: ECDSA Key Exchange -0.187498 | -1.047495 | /* -1.108945 | * Given the server's ECDH curve params and public key, generate our -0.077619 | * own ECDH key pair, and perform key exchange using the server's -0.022560 | * public key and our private key. The result is the premaster -0.016914 | * secret. -0.094852 | * -0.018576 | * SSLContext members valid on entry: -1.548635 | * if keyExchangeMethod == SSL_ECDHE_ECDSA or SSL_ECDHE_RSA: -0.920754 | * ecdhPeerPublic -0.682488 | * ecdhPeerCurve -0.211663 | * if keyExchangeMethod == SSL_ECDH_ECDSA or SSL_ECDH_RSA: -2.068567 | * peerPubKey, from which we infer ecdhPeerCurve -0.319416 | * -0.009878 | * SSLContext members valid on successful return: -0.239349 | * ecdhPrivate -0.029181 | * ecdhExchangePublic -0.014460 | * preMasterSecret -0.083251 | */ -0.067141 | static OSStatus -0.052161 | SSLGenClientECDHKeyAndExchange(SSLContext *ctx) -0.013992 | { -0.424013 | OSStatus ortn; - | -0.429852 | assert(ctx->protocolSide == kSSLClientSide); - | -1.027350 | switch(ctx->selectedCipherSpecParams.keyExchangeMethod) { -0.085659 | case SSL_ECDHE_ECDSA: -0.033092 | case SSL_ECDHE_RSA: -2.179580 | /* Server sent us an ephemeral key with peer curve specified */ -0.165047 | if(ctx->ecdhPeerPublic.data == NULL) { -0.238738 | sslErrorLog("SSLGenClientECDHKeyAndExchange: incomplete server params\n"); -0.052985 | return errSSLProtocol; -0.038628 | } -0.272191 | break; -0.010554 | case SSL_ECDH_ECDSA: -0.004980 | case SSL_ECDH_RSA: -0.923726 | { -1.458013 | /* No server key exchange; we have to get the curve from the key */ -0.276242 | if(ctx->peerPubKey == NULL) { -0.223243 | sslErrorLog("SSLGenClientECDHKeyAndExchange: no peer key\n"); -0.308795 | return errSSLInternal; -0.404543 | } - | -0.977712 | /* The peer curve is in the key's CSSM_X509_ALGORITHM_IDENTIFIER... */ -0.681581 | ortn = sslEcdsaPeerCurve(ctx->peerPubKey, &ctx->ecdhPeerCurve); -0.048628 | if(ortn) { -0.072800 | return ortn; -0.029992 | } -1.155163 | sslEcdsaDebug("SSLGenClientECDHKeyAndExchange: derived peerCurve %u", -0.082173 | (unsigned)ctx->ecdhPeerCurve); -0.107876 | break; -0.006778 | } -0.071547 | default: -0.809481 | /* shouldn't be here */ -0.119001 | assert(0); -0.157888 | return errSSLInternal; -0.062692 | } - | -2.304920 | /* Generate our (ephemeral) pair, or extract it from our signing identity */ -1.958743 | if((ctx->negAuthType == SSLClientAuth_RSAFixedECDH) || -0.083553 | (ctx->negAuthType == SSLClientAuth_ECDSAFixedECDH)) { -0.782682 | /* -1.994593 | * Client auth with a fixed ECDH key in the cert. Convert private key -1.839378 | * from SecKeyRef to CSSM format. We don't need ecdhExchangePublic -1.402995 | * because the server gets that from our cert. -0.022926 | */ -0.959861 | assert(ctx->signingPrivKeyRef != NULL); -0.401460 | #if USE_CDSA_CRYPTO -1.687044 | //assert(ctx->cspHand != 0); -1.258716 | sslFreeKey(ctx->cspHand, &ctx->ecdhPrivate, NULL); -0.415545 | SSLFreeBuffer(&ctx->ecdhExchangePublic); -0.367666 | ortn = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, (const CSSM_KEY **)&ctx->ecdhPrivate); -0.073353 | if(ortn) { -0.047810 | return ortn; -0.016283 | } -0.691528 | ortn = SecKeyGetCSPHandle(ctx->signingPrivKeyRef, &ctx->ecdhPrivCspHand); -0.023435 | if(ortn) { -0.459236 | sslErrorLog("SSLGenClientECDHKeyAndExchange: SecKeyGetCSPHandle err %d\n", -0.106272 | (int)ortn); -1.004619 | } -0.897238 | #endif -1.710681 | sslEcdsaDebug("+++ Extracted ECDH private key"); -0.340592 | } -0.110052 | else { -0.813993 | /* generate a new pair */ -0.343920 | ortn = sslEcdhGenerateKeyPair(ctx, ctx->ecdhPeerCurve); -0.013830 | if(ortn) { -0.018929 | return ortn; -0.008321 | } -0.339379 | #if USE_CDSA_CRYPTO -0.933906 | sslEcdsaDebug("+++ Generated %u bit (%u byte) ECDH key pair", -0.153092 | (unsigned)ctx->ecdhPrivate->KeyHeader.LogicalKeySizeInBits, -0.264942 | (unsigned)((ctx->ecdhPrivate->KeyHeader.LogicalKeySizeInBits + 7) / 8)); -0.096834 | #endif -0.134723 | } - | -4.479768 | -1.052007 | /* do the exchange --> premaster secret */ -0.196001 | ortn = sslEcdhKeyExchange(ctx, &ctx->preMasterSecret); -0.040868 | if(ortn) { -0.017580 | return ortn; -0.295400 | } -0.553224 | return errSecSuccess; -0.898082 | } - | -0.022522 | -1.004573 | /* -0.642154 | * Decode ECDH params and server public key. -0.101755 | */ -0.013000 | static OSStatus -0.158247 | SSLDecodeECDHKeyParams( -0.016748 | SSLContext *ctx, -0.017162 | uint8_t **charPtr, // IN/OUT -0.015084 | size_t length) -0.007330 | { -0.288276 | OSStatus err = errSecSuccess; - | -1.113213 | sslEcdsaDebug("+++ Decoding ECDH Server Key Exchange"); - | -0.180670 | assert(ctx->protocolSide == kSSLClientSide); -0.184669 | uint8_t *endCp = *charPtr + length; - | -0.101055 | /* Allow reuse via renegotiation */ -0.103793 | SSLFreeBuffer(&ctx->ecdhPeerPublic); - | -2.354099 | /*** ECParameters - just a curveType and a named curve ***/ - | -2.086612 | /* 1-byte curveType, we only allow one type */ -0.365788 | uint8_t curveType = **charPtr; -0.564500 | if(curveType != SSL_CurveTypeNamed) { -0.831896 | sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curveType (%u)\n", (unsigned)curveType); -0.080120 | return errSSLProtocol; -0.053207 | } -0.286055 | (*charPtr)++; -0.367532 | if(*charPtr > endCp) { -0.126427 | return errSSLProtocol; -0.089436 | } - | -1.376896 | /* two-byte curve */ -0.206762 | ctx->ecdhPeerCurve = SSLDecodeInt(*charPtr, 2); -0.045619 | (*charPtr) += 2; -0.059266 | if(*charPtr > endCp) { -0.005903 | return errSSLProtocol; -0.392873 | } -0.366943 | switch(ctx->ecdhPeerCurve) { -1.133516 | case SSL_Curve_secp256r1: -1.510627 | case SSL_Curve_secp384r1: -0.025989 | case SSL_Curve_secp521r1: -0.513384 | break; -0.067681 | default: -2.845714 | sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curve (%u)\n", -1.257283 | (unsigned)ctx->ecdhPeerCurve); -0.877411 | return errSSLProtocol; -0.591761 | } - | -0.610239 | sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: ecdhPeerCurve %u", -0.053762 | (unsigned)ctx->ecdhPeerCurve); - | -1.814979 | /*** peer public key as an ECPoint ***/ - | -1.345792 | /* -2.311797 | * The spec says the the max length of an ECPoint is 255 bytes, limiting -2.478002 | * this whole mechanism to a max modulus size of 1020 bits, which I find -0.919344 | * hard to believe... -0.204218 | */ -2.686970 | UInt32 len = SSLDecodeInt(*charPtr, 1); -0.913421 | (*charPtr)++; -1.232603 | if((*charPtr + len) > endCp) { -0.349960 | return errSSLProtocol; -0.114248 | } -0.997691 | err = SSLAllocBuffer(&ctx->ecdhPeerPublic, len); -0.220413 | if(err) { -0.050677 | return err; -0.014924 | } -0.173548 | memmove(ctx->ecdhPeerPublic.data, *charPtr, len); -0.156349 | (*charPtr) += len; - | -1.729085 | dumpBuf("client peer pub", &ctx->ecdhPeerPublic); - | -0.568021 | return err; -0.777009 | } - | -0.023410 | -0.632511 | static OSStatus -1.226741 | SSLEncodeECDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx) -1.713991 | { OSStatus err; -1.324439 | size_t outputLen; -3.367502 | int head; - | -0.986099 | assert(ctx->protocolSide == kSSLClientSide); -2.275162 | if ((err = SSLGenClientECDHKeyAndExchange(ctx)) != 0) -0.157992 | return err; - | -1.061080 | /* -1.814072 | * Per RFC 4492 5.7, if we're doing ECDSA_fixed_ECDH or RSA_fixed_ECDH -2.105878 | * client auth, we still send this message, but it's empty (because the -1.669024 | * server gets our public key from our cert). -0.097531 | */ -2.072502 | bool emptyMsg = false; -1.590162 | switch(ctx->negAuthType) { -0.895051 | case SSLClientAuth_RSAFixedECDH: -0.074510 | case SSLClientAuth_ECDSAFixedECDH: -0.038227 | emptyMsg = true; -0.028213 | break; -0.106786 | default: -0.015935 | break; -0.541831 | } -0.175568 | if(emptyMsg) { -0.388134 | outputLen = 0; -0.535452 | } -0.026081 | else { -0.747135 | outputLen = ctx->ecdhExchangePublic.length + 1; -0.212150 | } - | -1.042616 | keyExchange->contentType = SSL_RecordTypeHandshake; -1.006202 | assert(ctx->negProtocolVersion >= SSL_Version_3_0); -0.277943 | keyExchange->protocolVersion = ctx->negProtocolVersion; -1.263956 | head = SSLHandshakeHeaderSize(keyExchange); -0.845613 | if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head))) -0.260999 | return err; - | -1.291059 | uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen); -0.332271 | if(emptyMsg) { -0.879776 | sslEcdsaDebug("+++ Sending EMPTY ECDH Client Key Exchange"); -0.077747 | } -0.025681 | else { -1.867977 | /* just a 1-byte length here... */ -0.611305 | charPtr = SSLEncodeSize(charPtr, ctx->ecdhExchangePublic.length, 1); -0.128450 | memcpy(charPtr, ctx->ecdhExchangePublic.data, ctx->ecdhExchangePublic.length); -0.496531 | sslEcdsaDebug("+++ Encoded ECDH Client Key Exchange"); -0.375127 | } - | -0.446595 | dumpBuf("client pub key", &ctx->ecdhExchangePublic); -0.917474 | dumpBuf("client premaster", &ctx->preMasterSecret); -1.593928 | return errSecSuccess; -0.215940 | } - | -0.006472 | -2.690226 | -0.148518 | static OSStatus -0.745936 | SSLDecodePSKClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx) -0.460530 | { -1.801269 | OSStatus ortn = errSecSuccess; -2.223843 | unsigned int identityLen; - | -0.528825 | assert(ctx->protocolSide == kSSLServerSide); - | -1.815902 | /* this message simply contains the client's PSK identity */ -0.407854 | uint8_t *charPtr = keyExchange.data; -0.416190 | identityLen = SSLDecodeInt(charPtr, 2); -0.444381 | charPtr += 2; - | -2.236178 | SSLFreeBuffer(&ctx->pskIdentity); // allow reuse via renegotiation -0.093686 | ortn = SSLAllocBuffer(&ctx->pskIdentity, identityLen); -0.080600 | if(ortn) { -0.049102 | return ortn; -0.030979 | } -0.082969 | memmove(ctx->pskIdentity.data, charPtr, identityLen); - | -1.860138 | /* TODO: At this point we know the identity of the PSK client, -2.445351 | we should break out of the handshake, so we can select the appropriate -2.781057 | PreShared secret. As this stands, the preshared secret needs to be known -0.991497 | before the handshake starts. */ - | -2.213090 | size_t n=ctx->pskSharedSecret.length; - | -1.362452 | if(n==0) return errSSLBadConfiguration; - | -0.729277 | if ((ortn = SSLAllocBuffer(&ctx->preMasterSecret, 2*(n+2))) != 0) -0.088976 | return ortn; - | -0.432448 | uint8_t *p=ctx->preMasterSecret.data; - | -0.492625 | p = SSLEncodeInt(p, n, 2); -0.608852 | memset(p, 0, n); p+=n; -0.057071 | p = SSLEncodeInt(p, n, 2); -0.135059 | memcpy(p, ctx->pskSharedSecret.data, n); - | -0.521281 | dumpBuf("server premaster (PSK)", &ctx->preMasterSecret); - | -0.381969 | return ortn; -0.139138 | } - | -0.032984 | -0.143251 | static OSStatus -0.031893 | SSLEncodePSKClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx) -0.119472 | { -0.510769 | OSStatus err; -0.116068 | size_t outputLen; -0.066714 | int head; - | -0.070119 | assert(ctx->protocolSide == kSSLClientSide); - | -0.425511 | outputLen = ctx->pskIdentity.length+2; - | -0.008593 | keyExchange->contentType = SSL_RecordTypeHandshake; -0.014474 | assert(ctx->negProtocolVersion >= SSL_Version_3_0); -0.001736 | keyExchange->protocolVersion = ctx->negProtocolVersion; -0.002839 | head = SSLHandshakeHeaderSize(keyExchange); -0.006590 | if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head))) -0.005744 | return err; - | -0.052075 | uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen); - | -0.080417 | charPtr = SSLEncodeSize(charPtr, ctx->pskIdentity.length, 2); -0.021886 | memcpy(charPtr, ctx->pskIdentity.data, ctx->pskIdentity.length); - | -4.583159 | -2.321790 | /* We better have a pskSharedSecret already */ -0.084728 | size_t n=ctx->pskSharedSecret.length; - | -0.039871 | if(n==0) return errSSLBadConfiguration; - | -0.025325 | if ((err = SSLAllocBuffer(&ctx->preMasterSecret, 2*(n+2))) != 0) -0.018311 | return err; - | -0.015033 | uint8_t *p=ctx->preMasterSecret.data; - | -0.002564 | p = SSLEncodeInt(p, n, 2); -0.003833 | memset(p, 0, n); p+=n; -0.000349 | p = SSLEncodeInt(p, n, 2); -0.002733 | memcpy(p, ctx->pskSharedSecret.data, n); - | -0.033267 | dumpBuf("client premaster (PSK)", &ctx->preMasterSecret); - | -0.262430 | return errSecSuccess; -0.085629 | } - | -0.064352 | -2.550787 | // MARK: - -1.587259 | // MARK: Public Functions -1.830539 | OSStatus -0.767356 | SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx) -1.252102 | { OSStatus err; -2.723815 | -1.089965 | switch (ctx->selectedCipherSpecParams.keyExchangeMethod) -0.560242 | { case SSL_RSA: -0.222662 | case SSL_RSA_EXPORT: -2.640235 | #if APPLE_DH -0.405537 | case SSL_DHE_RSA: -0.160568 | case SSL_DHE_RSA_EXPORT: -0.214193 | case SSL_DHE_DSS: -0.006762 | case SSL_DHE_DSS_EXPORT: -0.309484 | #endif /* APPLE_DH */ -0.598565 | if ((err = SSLEncodeSignedServerKeyExchange(keyExch, ctx)) != 0) -0.039426 | return err; -0.098147 | break; -0.426545 | #if APPLE_DH -0.309432 | case SSL_DH_anon: -0.165344 | case SSL_DH_anon_EXPORT: -0.361357 | if ((err = SSLEncodeDHanonServerKeyExchange(keyExch, ctx)) != 0) -0.004097 | return err; -0.011741 | break; -1.083883 | #endif -0.316220 | default: -0.306728 | return errSecUnimplemented; -0.532234 | } - | -0.119763 | return errSecSuccess; -0.501510 | } -0.043249 | -0.044263 | OSStatus -0.886219 | SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx) -0.531823 | { -0.899986 | OSStatus err; -0.848078 | -0.235767 | switch (ctx->selectedCipherSpecParams.keyExchangeMethod) { -0.339585 | case SSL_RSA: -0.117258 | case SSL_RSA_EXPORT: -0.075066 | #if APPLE_DH -0.019255 | case SSL_DHE_RSA: -0.001183 | case SSL_DHE_RSA_EXPORT: -0.001462 | case SSL_DHE_DSS: -0.000423 | case SSL_DHE_DSS_EXPORT: -0.838379 | #endif -0.618943 | case SSL_ECDHE_ECDSA: -0.114855 | case SSL_ECDHE_RSA: -0.392402 | err = SSLDecodeSignedServerKeyExchange(message, ctx); -0.067747 | break; -0.052247 | #if APPLE_DH -0.021743 | case SSL_DH_anon: -0.011034 | case SSL_DH_anon_EXPORT: -0.017017 | err = SSLDecodeDHanonServerKeyExchange(message, ctx); -0.006599 | break; -0.019368 | #endif -0.023952 | default: -0.097074 | err = errSecUnimplemented; -0.810017 | break; -0.268892 | } - | -0.085918 | return err; -0.130447 | } -0.015297 | -0.046732 | OSStatus -0.366002 | SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx) -0.263514 | { OSStatus err; -0.212092 | -0.550729 | assert(ctx->protocolSide == kSSLClientSide); -0.549768 | -0.049763 | switch (ctx->selectedCipherSpecParams.keyExchangeMethod) { -0.155540 | case SSL_RSA: -0.181127 | case SSL_RSA_EXPORT: -1.294444 | sslDebugLog("SSLEncodeKeyExchange: RSA method\n"); -0.100846 | err = SSLEncodeRSAKeyExchange(keyExchange, ctx); -0.032659 | break; -0.395106 | #if APPLE_DH -0.050283 | case SSL_DHE_RSA: -0.016037 | case SSL_DHE_RSA_EXPORT: -0.027131 | case SSL_DHE_DSS: -0.000846 | case SSL_DHE_DSS_EXPORT: -0.379614 | case SSL_DH_anon: -0.005320 | case SSL_DH_anon_EXPORT: -0.064607 | sslDebugLog("SSLEncodeKeyExchange: DH method\n"); -0.194044 | err = SSLEncodeDHClientKeyExchange(keyExchange, ctx); -0.008021 | break; -0.179921 | #endif -0.323761 | case SSL_ECDH_ECDSA: -0.105103 | case SSL_ECDHE_ECDSA: -0.095296 | case SSL_ECDH_RSA: -0.003974 | case SSL_ECDHE_RSA: -0.092131 | case SSL_ECDH_anon: -0.089304 | sslDebugLog("SSLEncodeKeyExchange: ECDH method\n"); -0.014300 | err = SSLEncodeECDHClientKeyExchange(keyExchange, ctx); -0.009353 | break; -1.432608 | case TLS_PSK: -0.100532 | err = SSLEncodePSKClientKeyExchange(keyExchange, ctx); -0.035814 | break; -0.364363 | default: -0.547576 | sslErrorLog("SSLEncodeKeyExchange: unknown method (%d)\n", -0.245222 | ctx->selectedCipherSpecParams.keyExchangeMethod); -0.133917 | err = errSecUnimplemented; -0.944505 | } - | -0.283676 | return err; -0.189679 | } -0.009861 | -0.066993 | OSStatus -0.309766 | SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx) -0.168769 | { OSStatus err; -0.120416 | -0.212011 | switch (ctx->selectedCipherSpecParams.keyExchangeMethod) -0.066135 | { case SSL_RSA: -0.009293 | case SSL_RSA_EXPORT: -0.243843 | if ((err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0) -0.024685 | return err; -0.017757 | break; -0.319946 | #if APPLE_DH -0.307996 | case SSL_DH_anon: -0.534872 | case SSL_DHE_DSS: -0.020878 | case SSL_DHE_DSS_EXPORT: -0.051842 | case SSL_DHE_RSA: -0.004097 | case SSL_DHE_RSA_EXPORT: -0.070363 | case SSL_DH_anon_EXPORT: -0.686563 | sslDebugLog("SSLProcessKeyExchange: processing DH key exchange (%d)\n", -0.039529 | ctx->selectedCipherSpecParams.keyExchangeMethod); -0.102255 | if ((err = SSLDecodeDHClientKeyExchange(keyExchange, ctx)) != 0) -0.015881 | return err; -0.026837 | break; -1.050557 | #endif -0.323787 | case TLS_PSK: -0.156124 | if ((err = SSLDecodePSKClientKeyExchange(keyExchange, ctx)) != 0) -0.012522 | return err; -0.057319 | break; -0.291986 | default: -0.280356 | sslErrorLog("SSLProcessKeyExchange: unknown keyExchangeMethod (%d)\n", -0.011380 | ctx->selectedCipherSpecParams.keyExchangeMethod); -0.112462 | return errSecUnimplemented; -0.342983 | } - | -0.290754 | return errSecSuccess; -0.416820 | } -0.028029 | -0.191156 | OSStatus -1.201357 | SSLInitPendingCiphers(SSLContext *ctx) -0.618722 | { OSStatus err; -1.768141 | SSLBuffer key; -1.769092 | int keyDataLen; -3.081423 | -0.917308 | err = errSecSuccess; -1.100515 | key.data = 0; - | -0.577357 | keyDataLen = ctx->selectedCipherSpecParams.macSize + -0.345072 | ctx->selectedCipherSpecParams.keySize + -0.084993 | ctx->selectedCipherSpecParams.ivSize; -1.649465 | keyDataLen *= 2; /* two of everything */ - | -0.212183 | if ((err = SSLAllocBuffer(&key, keyDataLen))) -0.381989 | return err; -3.593413 | assert(ctx->sslTslCalls != NULL); -0.710446 | if ((err = ctx->sslTslCalls->generateKeyMaterial(key, ctx)) != 0) -1.315821 | goto fail; -0.882306 | -1.257645 | if((err = ctx->recFuncs->initPendingCiphers(ctx->recCtx, ctx->selectedCipher, (ctx->protocolSide==kSSLServerSide), key)) != 0) -0.176742 | goto fail; -0.482563 | -2.413076 | ctx->writePending_ready = 1; -0.158936 | ctx->readPending_ready = 1; -0.467761 | -0.401062 | fail: -0.107419 | SSLFreeBuffer(&key); -0.085940 | return err; -0.253904 | }