+/*
+ * Copyright (c) 1999-2001,2005-2014 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sslContext.h - Private SSL typedefs: SSLContext and its components
+ */
+
+#ifndef _SSLCONTEXT_H_
+#define _SSLCONTEXT_H_ 1
+
+#include "SecureTransport.h"
+#include "sslBuildFlags.h"
+
+#include <tls_handshake.h>
+#include <tls_record.h>
+#include <tls_stream_parser.h>
+
+#ifdef USE_CDSA_CRYPTO
+#include <Security/cssmtype.h>
+#else
+#if TARGET_OS_IPHONE
+#include <Security/SecDH.h>
+#include <Security/SecKeyInternal.h>
+#else
+#include "../sec/Security/SecDH.h" // hack to get SecDH.
+// typedef struct OpaqueSecDHContext *SecDHContext;
+#endif
+#include <corecrypto/ccec.h>
+#endif
+
+#include <CoreFoundation/CFRuntime.h>
+#include <AssertMacros.h>
+
+#include "sslPriv.h"
+#include "tls_ssl.h"
+#include "sslDigests.h"
+#include "sslRecord.h"
+#include "cipherSpecs.h"
+
+#include <dispatch/dispatch.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{ SSLReadFunc read;
+ SSLWriteFunc write;
+ SSLConnectionRef ioRef;
+} IOContext;
+
+//FIXME should not need this.
+typedef enum
+{
+ SSL_HdskStateUninit = 0, /* No Handshake yet */
+ SSL_HdskStatePending, /* Handshake in Progress */
+ SSL_HdskStateReady, /* Handshake is done */
+ SSL_HdskStateGracefulClose,
+ SSL_HdskStateErrorClose,
+ SSL_HdskStateNoNotifyClose, /* server disconnected with no
+ * notify msg */
+} SSLHandshakeState;
+
+#define SSLChangeHdskState(ctx, newState) { ctx->state=newState; }
+
+struct SSLContext
+{
+ CFRuntimeBase _base;
+ IOContext ioCtx;
+
+
+ const struct SSLRecordFuncs *recFuncs;
+ SSLRecordContextRef recCtx;
+
+ tls_handshake_t hdsk;
+
+ int readCipher_ready;
+ int writeCipher_ready;
+
+ SSLHandshakeState state;
+
+ /*
+ * Prior to successful protocol negotiation, negProtocolVersion
+ * is SSL_Version_Undetermined. Subsequent to successful
+ * negotiation, negProtocolVersion contains the actual over-the-wire
+ * protocol value.
+ *
+ * The Boolean versionEnable flags are set by
+ * SSLSetProtocolVersionEnabled or SSLSetProtocolVersion and
+ * remain invariant once negotiation has started. If there
+ * were a large number of these and/or we were adding new
+ * protocol versions on a regular basis, we'd probably want
+ * to implement these as a word of flags. For now, in the
+ * real world, this is the most straightforward implementation.
+ */
+ SSLProtocolVersion negProtocolVersion; /* negotiated */
+ SSLProtocolVersion clientReqProtocol; /* requested by client in hello msg */
+ SSLProtocolVersion minProtocolVersion;
+ SSLProtocolVersion maxProtocolVersion;
+ Boolean isDTLS; /* if this is a Datagram Context */
+ SSLProtocolSide protocolSide; /* ConnectionEnd enum { server, client } in rfc5246. */
+
+ SSLBuffer dtlsCookie; /* DTLS ClientHello cookie */
+
+
+ uint16_t selectedCipher; /* currently selected */
+
+
+ tls_private_key_t signingPrivKeyRef; /* our private signing key */
+
+ tls_private_key_t encryptPrivKeyRef; /* our private encrypt key, for
+ * server-initiated key exchange */
+
+
+ /* Server DH Parameters */
+ SSLBuffer dhParamsEncoded; /* PKCS3 encoded blob - prime + generator */
+
+ /*
+ * Various cert chains.
+ * For all three, the root is the last in the chain.
+ */
+ SSLCertificate *localCert;
+ SSLCertificate *encryptCert;
+ CFArrayRef peerCert;
+
+ /*
+ * The arrays we are given via SSLSetCertificate() and SSLSetEncryptionCertificate().
+ * We keep them here, refcounted, solely for the associated getters.
+ */
+ CFArrayRef localCertArray;
+ CFArrayRef encryptCertArray;
+
+ /* peer certs as SecTrustRef */
+ SecTrustRef peerSecTrust;
+
+ CFMutableArrayRef trustedCerts;
+ Boolean trustedCertsOnly;
+
+ /*
+ * trusted leaf certs as specified in SSLSetTrustedLeafCertificates()
+ */
+ CFArrayRef trustedLeafCerts;
+
+ Boolean allowExpiredCerts;
+ Boolean allowExpiredRoots;
+ Boolean enableCertVerify;
+
+ SSLBuffer sessionID;
+ SSLBuffer peerID;
+ SSLBuffer resumableSession; /* We keep a copy for now - but eventually this should go away if we get refcounted SSLBuffers */
+
+ uint16_t *validCipherSuites; /* context's valid suites */
+ unsigned numValidCipherSuites; /* size of validCipherSuites */
+
+
+ uint16_t *ecdhCurves;
+ unsigned ecdhNumCurves;
+
+ /* server-side only */
+ SSLAuthenticate clientAuth; /* kNeverAuthenticate, etc. */
+ //Boolean tryClientAuth;
+
+ /* client and server */
+ SSLClientCertificateState clientCertState;
+
+ DNListElem *acceptableDNList; /* client and server */
+ CFMutableArrayRef acceptableCAs; /* server only - SecCertificateRefs */
+
+ bool certRequested;
+ bool certSent;
+ bool certReceived;
+ bool x509Requested;
+
+ unsigned sessionMatch;
+
+
+ /* Transport layer fields */
+ SSLBuffer receivedDataBuffer;
+ size_t receivedDataPos;
+
+ Boolean allowAnyRoot; // don't require known roots
+ Boolean sentFatalAlert; // this session terminated by fatal alert
+ Boolean rsaBlindingEnable;
+ Boolean oneByteRecordEnable; /* enable 1/n-1 data splitting for TLSv1 and SSLv3 */
+
+ /* optional session cache timeout (in seconds) override - 0 means default */
+ uint32_t sessionCacheTimeout;
+
+ /* optional SessionTicket */
+ SSLBuffer sessionTicket;
+
+ /* optional callback to obtain master secret, with its opaque arg */
+ SSLInternalMasterSecretFunction masterSecretCallback;
+ const void *masterSecretArg;
+
+ #if SSL_PAC_SERVER_ENABLE
+ /* server PAC resume sets serverRandom early to allow for secret acquisition */
+ uint8_t serverRandomValid;
+ #endif
+
+ Boolean anonCipherEnable;
+
+ /* optional switches to enable additional returns from SSLHandshake */
+ Boolean breakOnServerAuth;
+ Boolean breakOnCertRequest;
+ Boolean breakOnClientAuth;
+ Boolean signalServerAuth;
+ Boolean signalCertRequest;
+ Boolean signalClientAuth;
+
+ /* true iff ECDSA/ECDH ciphers are configured */
+ Boolean ecdsaEnable;
+
+ /* List of peer-specified supported_signature_algorithms */
+ unsigned numPeerSigAlgs;
+ const tls_signature_and_hash_algorithm *peerSigAlgs;
+
+ /* List of server-specified client auth types */
+ unsigned numAuthTypes;
+ const tls_client_auth_type *clientAuthTypes;
+
+ /* client auth type actually negotiated */
+ tls_client_auth_type negAuthType;
+
+ /* Timeout for DTLS retransmit */
+ CFAbsoluteTime timeout_deadline;
+ CFAbsoluteTime timeout_duration;
+ size_t mtu;
+
+ /* RFC 5746: Secure renegotiation */
+ Boolean secure_renegotiation;
+ Boolean secure_renegotiation_received;
+ SSLBuffer ownVerifyData;
+ SSLBuffer peerVerifyData;
+
+ /* RFC 4279: TLS PSK */
+ SSLBuffer pskSharedSecret;
+ SSLBuffer pskIdentity;
+
+ /* TLS False Start */
+ Boolean falseStartEnabled; //FalseStart enabled (by API call)
+ /* Fallback behavior */
+ Boolean fallbackEnabled; // Fallback behavior enabled.
+ /* NPN */
+ SSLNPNFunc npnFunc;
+ void *npnFuncInfo;
+};
+
+OSStatus SSLUpdateNegotiatedClientAuthType(SSLContextRef ctx);
+
+Boolean sslIsSessionActive(const SSLContext *ctx);
+
+static inline bool sslVersionIsLikeTls12(SSLContext *ctx)
+{
+ check(ctx->negProtocolVersion!=SSL_Version_Undetermined);
+ return ctx->isDTLS ? ctx->negProtocolVersion > DTLS_Version_1_0 : ctx->negProtocolVersion >= TLS_Version_1_2;
+}
+
+/* This is implemented in tls_callbacks.c */
+ int sslGetSessionID(SSLContext *myCtx, SSLBuffer *sessionID);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSLCONTEXT_H_ */