# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:47 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: AppleCSP
ProjectVersion: 16
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:51 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: AppleCSPDL
ProjectVersion: 15
const char *const SSDatabaseImpl::DBBlobRelationName = "DBBlob";
-SSDatabaseImpl::SSDatabaseImpl(ClientSession &inClientSession,
- const CssmClient::DL &dl,
+SSDatabaseImpl::SSDatabaseImpl(ClientSession &inClientSession, const CssmClient::DL &dl,
const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
-: Db::Impl(dl, inDbName, inDbLocation), mClientSession(inClientSession), mSSDbHandle(noDb)
+ : Db::Impl(dl, inDbName, inDbLocation), mClientSession(inClientSession), mSSDbHandle(noDb)
{
}
SSDatabaseImpl::dbHandle()
{
activate();
+ if (mForked()) {
+ // re-establish the dbHandle with the SecurityServer
+ CssmDataContainer dbb(allocator());
+ mDbBlobId->get(NULL, &dbb);
+ mSSDbHandle = mClientSession.decodeDb(mIdentifier,
+ AccessCredentials::overlay(accessCredentials()), dbb);
+ }
return mSSDbHandle;
}
void
SSDatabaseImpl::create(const DLDbIdentifier &dlDbIdentifier)
{
+ mIdentifier = dlDbIdentifier;
DbImpl::create();
try
void
SSDatabaseImpl::open(const DLDbIdentifier &dlDbIdentifier)
{
+ mIdentifier = dlDbIdentifier;
Db::Impl::open();
DbCursor cursor(SSDatabase(this));
#define _H_SSDATABASE_
#include <Security/dlclient.h>
+#include <Security/unix++.h>
#include <Security/SecurityServerClient.h>
class SSCSPDLSession;
kDefaultIdleTimeout = 5 * 60, // 5 minute default autolock time
kDefaultLockOnSleep = true
};
-
+
+ DLDbIdentifier mIdentifier;
+ UnixPlusPlus::ForkMonitor mForked;
+
SecurityServer::ClientSession &mClientSession;
SecurityServer::DbHandle mSSDbHandle;
CssmClient::DbUniqueRecord mDbBlobId;
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:52 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: AppleDL
ProjectVersion: 13
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:52 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: AppleX509CL
ProjectVersion: 3
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:53 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: AppleX509TP
ProjectVersion: 3
CSSM_RETURN TPCertGroup::getReturnCode(
CSSM_RETURN constructStatus,
CSSM_BOOL allowExpired,
+ CSSM_BOOL allowExpiredRoot,
CSSM_RETURN policyStatus /* = CSSM_OK */)
{
if(constructStatus) {
bool expired = false;
bool notValid = false;
for(unsigned i=0; i<mNumCerts; i++) {
- if(mCertInfo[i]->isExpired()) {
+ if(mCertInfo[i]->isExpired() &&
+ !(allowExpiredRoot && mCertInfo[i]->isSelfSigned())) {
expired = true;
}
if(mCertInfo[i]->isNotValidYet()) {
CSSM_RETURN getReturnCode(
CSSM_RETURN constructStatus,
CSSM_BOOL allowExpired,
+ CSSM_BOOL allowExpiredRoot,
CSSM_RETURN policyStatus = CSSM_OK);
CssmAllocator
return CSSM_ALGID_NONE;
}
}
+
+/*
+ * Convert a C string to lower case in place. NULL terminator not needed.
+ */
+void tpToLower(
+ char *str,
+ unsigned strLen)
+{
+ for(unsigned i=0; i<strLen; i++) {
+ *str++ = tolower(*str);
+ }
+}
+
+
+/*
+ * Compare hostname, is presented to the TP in
+ * CSSM_APPLE_TP_SSL_OPTIONS.ServerName, to a server name obtained
+ * from the server's cert (i.e., from subjectAltName or commonName).
+ * Limited wildcard checking is performed here.
+ *
+ * The incoming hostname is assumed to have been processed by tpToLower();
+ * we'll perform that processing on serverName here.
+ *
+ * Returns CSSM_TRUE on match, else CSSM_FALSE.
+ */
+CSSM_BOOL tpCompareHostNames(
+ const char *hostName, // spec'd by app, tpToLower'd
+ uint32 hostNameLen,
+ char *serverName, // from cert, we tpToLower
+ uint32 serverNameLen)
+{
+ tpToLower(serverName, serverNameLen);
+
+ /* tolerate optional NULL terminators for both */
+ if(hostName[hostNameLen - 1] == '\0') {
+ hostNameLen--;
+ }
+ if(serverName[serverNameLen - 1] == '\0') {
+ serverNameLen--;
+ }
+
+ /* case 1: exact match */
+ if((serverNameLen == hostNameLen) &&
+ !memcmp(serverName, hostName, serverNameLen)) {
+ return CSSM_TRUE;
+ }
+
+ /* case 2: handle optional '*' in cert's server name */
+ if(serverName[0] == '*') {
+ /* last (serverNameLen - 1) chars have to match */
+ unsigned effectLen = serverNameLen - 1; // skip '*'
+ if(serverNameLen < effectLen) {
+ errorLog0("tp_verifySslOpts: subject/server name wildcard "
+ "mismatch (1)");
+ return CSSM_FALSE;
+ }
+ else if(memcmp(serverName+1, // skip '*'
+ hostName + hostNameLen - effectLen,
+ effectLen)) {
+ errorLog0("tp_verifySslOpts: subject/server name wildcard "
+ "mismatch (2)");
+ return CSSM_FALSE;
+ }
+ else {
+ /* wildcard match */
+ return CSSM_TRUE;
+ }
+ }
+ else {
+ /* mismatch */
+ errorLog0("tp_verifySslOpts: subject/server name mismatch");
+ return CSSM_FALSE;
+ }
+}
const CSSM_OID *oid,
CSSM_ALGORITHMS *keyAlg); // RETURNED
+void tpToLower(
+ char *str,
+ unsigned strLen);
+
+CSSM_BOOL tpCompareHostNames(
+ const char *hostName, // spec'd by app, tpToLower'd
+ uint32 hostNameLen,
+ char *serverName, // from cert, we tpToLower
+ uint32 serverNameLen);
+
+
#ifdef __cplusplus
}
#endif
const CSSM_TP_CALLERAUTH_CONTEXT *cred;
CSSM_OID_PTR oid = NULL;
TPCertGroup *tpCertGroup = NULL; // created by
- // CertGroupConstructPriv
+ // CertGroupConstructPriv
TPCertInfo *certInfo = NULL;
CSSM_BOOL allowExpired = CSSM_FALSE;
+ CSSM_BOOL allowExpiredRoot = CSSM_FALSE;
/* declare volatile as compiler workaround to avoid caching in CR4 */
const CSSM_APPLE_TP_ACTION_DATA * volatile actionData = NULL;
const CSSM_APPLE_TP_SSL_OPTIONS *sslOpts = NULL;
if(actionData->ActionFlags & CSSM_TP_ACTION_ALLOW_EXPIRED) {
allowExpired = CSSM_TRUE;
}
+ if(actionData->ActionFlags & CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT) {
+ allowExpiredRoot = CSSM_TRUE;
+ }
}
/* optional, may be NULL */
}
CSSM_RETURN outErr = tpCertGroup->getReturnCode(constructReturn,
- allowExpired, policyReturn);
+ allowExpired, allowExpiredRoot, policyReturn);
/* delete (internal use only) TPCertGroup */
delete tpCertGroup;
/* create signature context */
ourRtn = CSSM_CSP_CreateSignatureContext(certReq->cspHand,
certReq->signatureAlg,
- NULL, // AccessCred
+ (CallerAuthContext ? CallerAuthContext->CallerCredentials : NULL),
certReq->issuerPrivateKey,
&sigContext);
if(ourRtn) {
}
#endif /* TP_ROOT_CERT_ENABLE */
-/*
- * Convert a C string to lower case in place. NULL terminator not needed.
- */
-static void tpToLower(
- char *str,
- unsigned strLen)
-{
- for(unsigned i=0; i<strLen; i++) {
- *str++ = tolower(*str);
- }
-}
-
-/*
- * Verify SSL options. Currently this just consists of matching the
- * leaf cert's subject common name against the caller's (optional)
- * server name.
+/*
+ * See if cert's Subject.commonName matches caller-specified hostname.
+ * Returns CSSM_TRUE if match, else returns CSSM_FALSE.
*/
-static CSSM_RETURN tp_verifySslOpts(
- TPCertGroup &certGroup,
- const CSSM_APPLE_TP_SSL_OPTIONS *sslOpts)
+static CSSM_BOOL tpCompareCommonName(
+ TPCertInfo &cert,
+ const char *hostName,
+ uint32 hostNameLen)
{
- if(sslOpts == NULL) {
- /* optional */
- return CSSM_OK;
- }
-
- CSSM_DATA_PTR subjNameData = NULL;
- char *serverName = NULL;
- unsigned serverNameLen = sslOpts->ServerNameLen;
- char *commonName = NULL;
- uint32 commonNameLen = 0;
-
- if(serverNameLen == 0) {
- /* optional */
- return CSSM_OK;
- }
- if(sslOpts->ServerName == NULL) {
- return CSSMERR_TP_INVALID_POINTER;
- }
+ char *commonName = NULL; // from cert's subject name
+ uint32 commonNameLen = 0;
+ CSSM_DATA_PTR subjNameData = NULL;
+ CSSM_RETURN crtn;
+ CSSM_BOOL ourRtn = CSSM_FALSE;
- /* Obtain subject name of leaf cert in CSSM_X509_NAME_PTR form */
- TPCertInfo *leaf = certGroup.certAtIndex(0);
- assert(leaf != NULL);
- CSSM_RETURN crtn;
- crtn = leaf->fetchField(&CSSMOID_X509V1SubjectNameCStruct, &subjNameData);
+ crtn = cert.fetchField(&CSSMOID_X509V1SubjectNameCStruct, &subjNameData);
if(crtn) {
/* should never happen, we shouldn't be here if there is no subject */
- errorLog0("tp_verifySslOpts: error retrieving subject name\n");
- return crtn;
+ errorLog0("tp_verifySslOpts: error retrieving subject name");
+ return CSSM_FALSE;
}
CSSM_X509_NAME_PTR x509name = (CSSM_X509_NAME_PTR)subjNameData->Data;
if((x509name == NULL) || (subjNameData->Length != sizeof(CSSM_X509_NAME))) {
- errorLog0("tp_verifySslOpts: malformed CSSM_X509_NAME\n");
- crtn = CSSMERR_TP_INVALID_CERTGROUP;
- goto done;
+ errorLog0("tp_verifySslOpts: malformed CSSM_X509_NAME");
+ cert.freeField(&CSSMOID_X509V1SubjectNameCStruct, subjNameData);
+ return CSSM_FALSE;
}
/* Now grunge thru the X509 name looking for a common name */
if(tpCompareOids(&ptvp->type, &CSSMOID_CommonName)) {
commonName = (char *)ptvp->value.Data;
commonNameLen = ptvp->value.Length;
- break;
+ ourRtn = tpCompareHostNames(hostName, hostNameLen,
+ commonName, commonNameLen);
+ if(ourRtn) {
+ /* success */
+ break;
+ }
+ /* else keep going, maybe there's another common name */
}
}
+ if(ourRtn) {
+ break;
+ }
}
- if(commonName == NULL) {
- errorLog0("tp_verifySslOpts: NO COMMON NAME in subject\n");
- crtn = CSSMERR_TP_VERIFY_ACTION_FAILED;
- goto done;
- }
+ cert.freeField(&CSSMOID_X509V1SubjectNameCStruct, subjNameData);
+ return ourRtn;
+}
+
+/*
+ * Compare ASCII form of an IP address to a CSSM_DATA containing
+ * the IP address's numeric components. Returns true on match.
+ */
+static CSSM_BOOL tpCompIpAddrStr(
+ const char *str,
+ unsigned strLen,
+ const CSSM_DATA *numeric)
+{
+ const char *cp = str;
+ const char *nextDot;
+ char buf[100];
- /* tolerate optional NULL terminators for both */
- if(commonName[commonNameLen - 1] == '\0') {
- commonNameLen--;
+ if((numeric == NULL) || (numeric->Length == 0) || (str == NULL)) {
+ return CSSM_FALSE;
}
- if(sslOpts->ServerName[serverNameLen - 1] == '\0') {
- serverNameLen--;
+ if(cp[strLen - 1] == '\0') {
+ /* ignore NULL terminator */
+ strLen--;
}
+ for(unsigned dex=0; dex<numeric->Length; dex++) {
+ /* cp points to start of current string digit */
+ /* find next dot */
+ const char *lastChar = cp + strLen;
+ nextDot = cp + 1;
+ for( ; nextDot<lastChar; nextDot++) {
+ if(*nextDot == '.') {
+ break;
+ }
+ }
+ if(nextDot == lastChar) {
+ /* legal and required on last digit */
+ if(dex != (numeric->Length - 1)) {
+ return CSSM_FALSE;
+ }
+ }
+ else if(dex == (numeric->Length - 1)) {
+ return CSSM_FALSE;
+ }
+ unsigned digLen = nextDot - cp;
+ if(digLen >= sizeof(buf)) {
+ /* preposterous */
+ return CSSM_FALSE;
+ }
+ memmove(buf, cp, digLen);
+ buf[digLen] = '\0';
+ /* incr digLen to include the next dot */
+ digLen++;
+ cp += digLen;
+ strLen -= digLen;
+ int digVal = atoi(buf);
+ if(digVal != numeric->Data[dex]) {
+ return CSSM_FALSE;
+ }
+ }
+ return CSSM_TRUE;
+}
+
+/*
+ * See if cert's subjectAltName matches caller-specified hostname, either
+ * as a dnsName or an iPAddress.
+ *
+ * Returns CSSM_TRUE if match, else returns CSSM_FALSE. Also indicates
+ * whether or not a dnsName was found (in which case the subject's
+ * common name should NOT be a candidate for verification).
+ */
+static CSSM_BOOL tpCompareSubjectAltName(
+ TPCertInfo &cert,
+ const char *hostName,
+ uint32 hostNameLen,
+ bool &dnsNameFound) // RETURNED
+{
+ CSSM_DATA_PTR subjAltNameData = NULL;
+ CSSM_RETURN crtn;
+ CSSM_BOOL ourRtn = CSSM_FALSE;
- /* convert both name strings to lower case. The one in the X509 Name can
- * be done in place; we have to malloc and copy the caller's string. */
- tpToLower(commonName, commonNameLen);
- serverName = (char *)certGroup.alloc().malloc(serverNameLen);
- memmove(serverName, sslOpts->ServerName, serverNameLen);
- tpToLower(serverName, serverNameLen);
-
- /* case 1: exact match */
- if((serverNameLen == commonNameLen) &&
- !memcmp(commonName, serverName, commonNameLen)) {
- crtn = CSSM_OK;
- goto done;
+ dnsNameFound = false;
+ crtn = cert.fetchField(&CSSMOID_SubjectAltName, &subjAltNameData);
+ if(crtn) {
+ /* common failure, no subjectAltName found */
+ return CSSM_FALSE;
}
+ CSSM_X509_EXTENSION_PTR exten =
+ (CSSM_X509_EXTENSION_PTR)subjAltNameData->Data;
+ /* Paranoid check of extension integrity */
+ if((exten == NULL) ||
+ (subjAltNameData->Length != sizeof(CSSM_X509_EXTENSION)) ||
+ (exten->format != CSSM_X509_DATAFORMAT_PARSED) ||
+ (exten->value.parsedValue == NULL)) {
+ errorLog0("tpCompareSubjectAltName: malformed CSSM_X509_EXTENSION");
+ cert.freeField(&CSSMOID_SubjectAltName, subjAltNameData);
+ return CSSM_FALSE;
+ }
+
+ CE_GeneralNames *names = (CE_GeneralNames *)exten->value.parsedValue;
+ char *serverName;
+ unsigned serverNameLen;
- /* case 2: handle optional '*' in cert's common name */
- if(commonName[0] == '*') {
- /* last (commonNameLen - 1) chars have to match */
- unsigned effectLen = commonNameLen - 1; // skip '*'
- if(serverNameLen < effectLen) {
- errorLog0("tp_verifySslOpts: subject/server name wildcard mismatch (1)\n");
- crtn = CSSMERR_TP_VERIFY_ACTION_FAILED;
- }
- else if(memcmp(commonName+1, // skip '*'
- serverName + serverNameLen - effectLen,
- effectLen)) {
- errorLog0("tp_verifySslOpts: subject/server name wildcard mismatch (2)\n");
- crtn = CSSMERR_TP_VERIFY_ACTION_FAILED;
+ /* Search thru the CE_GeneralNames looking for a DNSName or IP Address */
+ for(unsigned dex=0; dex<names->numNames; dex++) {
+ CE_GeneralName *name = &names->generalName[dex];
+ switch(name->nameType) {
+ case GNT_IPAddress:
+ ourRtn = tpCompIpAddrStr(hostName, hostNameLen, &name->name);
+ break;
+
+ case GNT_DNSName:
+ if(name->berEncoded) {
+ errorLog0("tpCompareSubjectAltName: malformed "
+ "CE_GeneralName (1)\n");
+ break;
+ }
+ serverName = (char *)name->name.Data;
+ if(serverName == NULL) {
+ errorLog0("tpCompareSubjectAltName: malformed "
+ "CE_GeneralName (2)\n");
+ break;
+ }
+ serverNameLen = name->name.Length;
+ ourRtn = tpCompareHostNames(hostName, hostNameLen,
+ serverName, serverNameLen);
+ dnsNameFound = true;
+ break;
+
+ default:
+ /* not interested, proceed to next name */
+ break;
}
- else {
- /* wildcard match */
- crtn = CSSM_OK;
+ if(ourRtn) {
+ /* success */
+ break;
}
}
- else {
- /* mismatch */
- errorLog0("tp_verifySslOpts: subject/server name mismatch\n");
- crtn = CSSMERR_TP_VERIFY_ACTION_FAILED;
+ cert.freeField(&CSSMOID_SubjectAltName, subjAltNameData);
+ return ourRtn;
+}
+
+/* is host name in the form of a.b.c.d, where a,b,c, and d are digits? */
+static CSSM_BOOL tpIsNumeric(
+ const char *hostName,
+ unsigned hostNameLen)
+{
+ if(hostName[hostNameLen - 1] == '\0') {
+ /* ignore NULL terminator */
+ hostNameLen--;
+ }
+ for(unsigned i=0; i<hostNameLen; i++) {
+ char c = *hostName++;
+ if(isdigit(c)) {
+ continue;
+ }
+ if(c != '.') {
+ return CSSM_FALSE;
+ }
+ }
+ return CSSM_TRUE;
+}
+
+/*
+ * Verify SSL options. Currently this just consists of matching the
+ * leaf cert's subject common name against the caller's (optional)
+ * server name.
+ */
+static CSSM_RETURN tp_verifySslOpts(
+ TPCertGroup &certGroup,
+ const CSSM_APPLE_TP_SSL_OPTIONS *sslOpts)
+{
+ if(sslOpts == NULL) {
+ /* optional */
+ return CSSM_OK;
}
-done:
- if(subjNameData != NULL) {
- leaf->freeField(&CSSMOID_X509V1SubjectNameCStruct, subjNameData);
+
+ unsigned hostNameLen = sslOpts->ServerNameLen;
+
+ if(hostNameLen == 0) {
+ /* optional */
+ return CSSM_OK;
}
- if(serverName != NULL) {
- certGroup.alloc().free(serverName);
+ if(sslOpts->ServerName == NULL) {
+ return CSSMERR_TP_INVALID_POINTER;
+ }
+
+ /* convert caller's hostname string to lower case */
+ char *hostName = (char *)certGroup.alloc().malloc(hostNameLen);
+ memmove(hostName, sslOpts->ServerName, hostNameLen);
+ tpToLower(hostName, hostNameLen);
+
+ TPCertInfo *leaf = certGroup.certAtIndex(0);
+ assert(leaf != NULL);
+
+ CSSM_BOOL match = CSSM_FALSE;
+
+ /* First check subjectAltName... */
+ bool dnsNameFound = false;
+ match = tpCompareSubjectAltName(*leaf, hostName, hostNameLen,
+ dnsNameFound);
+ /*
+ * Then common name, if
+ * -- no match from subjectAltName, AND
+ * -- dnsName was NOT found, AND
+ * -- hostName is not strictly numeric form (1.2.3.4)
+ */
+ if(!match && !dnsNameFound && !tpIsNumeric(hostName, hostNameLen)) {
+ match = tpCompareCommonName(*leaf, hostName, hostNameLen);
}
- if(crtn == CSSMERR_TP_VERIFY_ACTION_FAILED) {
+ certGroup.alloc().free(hostName);
+ if(match) {
+ return CSSM_OK;
+ }
+ else {
leaf->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH);
+ return CSSMERR_TP_VERIFY_ACTION_FAILED;
}
- return crtn;
}
/*
#include <Security/SecKeychainItem.h>
#include <Security/SecKeychain.h>
+#include <Security/SecKey.h>
+#include <Security/SecAccess.h>
+#include <Security/SecACL.h>
#include <Security/certextensions.h>
#include <Security/cssmapple.h>
#include <Security/oidsattr.h>
#include "CertUI.h"
#include <CoreFoundation/CoreFoundation.h>
#include <Security/utilities.h>
+#include <Security/aclclient.h>
/* will change soon */
#include <Security/SecCertificate.h>
#define SEC_CERT_ADD_TO_KC 1
/* SecKeyCreatePair() implemented */
-#define SEC_KEY_CREATE_PAIR 0
+#define SEC_KEY_CREATE_PAIR 1
#if !SEC_KEY_CREATE_PAIR
/* munge Label attr if manually generating keys */
}
#if SEC_KEY_CREATE_PAIR
-#error Work needed to generate key pair using Keychain.
+/* #error Work needed to generate key pair using Keychain. */
#else
/*
const char *keyLabel, // C string
CU_KeyUsage keyUsage, // CUK_Signing, etc.
CSSM_BOOL verbose,
- CSSM_KEY_PTR *pubKeyPtr, // mallocd, created, RETURNED
- CSSM_KEY_PTR *privKeyPtr) // mallocd, created, RETURNED
+ const CSSM_KEY **pubKeyPtr, // mallocd, created, RETURNED
+ const CSSM_KEY **privKeyPtr) // mallocd, created, RETURNED
{
CSSM_KEY_PTR pubKey = reinterpret_cast<CSSM_KEY_PTR>(
APP_MALLOC(sizeof(CSSM_KEY)));
CSSM_TP_HANDLE tpHand, // eventually, a SecKeychainRef
CSSM_CL_HANDLE clHand,
CSSM_CSP_HANDLE cspHand,
- CSSM_KEY_PTR subjPubKey,
- CSSM_KEY_PTR signerPrivKey,
+ const CSSM_KEY *subjPubKey,
+ const CSSM_KEY *signerPrivKey,
CSSM_ALGORITHMS sigAlg,
const CSSM_OID *sigOid,
CU_KeyUsage keyUsage, // kKeyUseSigning, etc.
}
CallerAuthContext.Policy.NumberOfPolicyIds = 1;
CallerAuthContext.Policy.PolicyIds = &policyId;
+ CssmClient::AclFactory factory;
+ CallerAuthContext.CallerCredentials = const_cast<Security::AccessCredentials *>(factory.promptCred());
CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest(tpHand,
NULL, // PreferredAuthority
CSSM_CSP_HANDLE cspHand = 0;
CSSM_TP_HANDLE tpHand = 0;
CSSM_CL_HANDLE clHand = 0;
- CSSM_KEY_PTR pubKey;
- CSSM_KEY_PTR privKey;
+ const CSSM_KEY *pubKey;
+ const CSSM_KEY *privKey;
int arg;
char *argp;
CSSM_BOOL verbose = CSSM_FALSE;
CU_KeyUsage keyUsage = 0;
bool isRoot;
CSSM_DATA keyLabel;
- #if !SEC_KEY_CREATE_PAIR && !MUNGE_LABEL_ATTR
+ #if SEC_KEY_CREATE_PAIR
+ CSSM_KEYUSE pubKeyUse = 0;
+ CSSM_KEYUSE privKeyUse = 0;
+ CSSM_KEYATTR_FLAGS pubKeyAttrs;
+ CSSM_KEYATTR_FLAGS privKeyAttrs;
+ CFStringRef description = NULL;
+ SecAccessRef access = NULL;
+ CFArrayRef acls = NULL;
+ SecACLRef acl = NULL;
+ bool aclFound = false;
+ CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR promptSelector =
+ {
+ CSSM_ACL_KEYCHAIN_PROMPT_CURRENT_VERSION, 0
+ };
+ SecKeyRef pubKeyRef = 0, privKeyRef = 0;
+ #elif !MUNGE_LABEL_ATTR
CSSM_DATA pubKeyHash = {3, (uint8 *)"foo"};
#endif
CSSM_BOOL createCsr = CSSM_FALSE; // else create cert
int optArgs = 0;
-
+
/* command line arguments */
char *fileName = NULL;
CSSM_BOOL pemFormat = CSSM_TRUE;
}
printf("...Generating key pair...\n");
+#if SEC_KEY_CREATE_PAIR
+
+ description = CFStringCreateWithCString(NULL, labelBuf, kCFStringEncodingMacRoman);
+ ortn = SecAccessCreate(description, NULL, &access);
+ if(ortn) {
+ printf("Error creating SecAccessRef; aborting.\n");
+ goto abort;
+ }
+ ortn = SecAccessCopyACLList(access, &acls);
+ if (ortn) {
+ printf("Error calling SecAccessCopyACLList; aborting.\n");
+ goto abort;
+ }
+ for (CFIndex ix = 0; ix < CFArrayGetCount(acls); ++ix)
+ {
+ CSSM_ACL_AUTHORIZATION_TAG tags[20];
+ uint32 tagCount = 20;
+
+ acl = (SecACLRef)CFArrayGetValueAtIndex(acls, ix);
+ ortn = SecACLGetAuthorizations(acl, tags, &tagCount);
+ if(ortn) {
+ printf("Error calling SecACLGetAuthorizations; aborting.\n");
+ goto abort;
+ }
+
+ for (uint32 tix = 0; tix < tagCount; ++tix)
+ {
+ if (tags[tix] == CSSM_ACL_AUTHORIZATION_DECRYPT
+ || tags[tix] == CSSM_ACL_AUTHORIZATION_ANY)
+ {
+ aclFound = true;
+ break;
+ }
+ }
+
+ if (aclFound)
+ break;
+ }
+
+ if (!aclFound) {
+ printf("Could not find ACL for decrypt right; aborting.\n");
+ goto abort;
+ }
+
+ // Make the ACL an any allowed acl by setting the trusted application list to NULL
+ ortn = SecACLSetSimpleContents(acl, NULL, description, &promptSelector);
+ if(ortn) {
+ printf("Error calling SecACLSetSimpleContents; aborting.\n");
+ goto abort;
+ }
+
+ pubKeyAttrs = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT;
+ privKeyAttrs = CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT;
+
+ if(keyUsage & kKeyUseSigning) {
+ pubKeyUse |= CSSM_KEYUSE_VERIFY;
+ privKeyUse |= CSSM_KEYUSE_SIGN;
+ }
+ if(keyUsage & kKeyUseEncrypting) {
+ pubKeyUse |= (CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_WRAP);
+ privKeyUse |= (CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_UNWRAP);
+ }
+
+ ortn = SecKeyCreatePair(kcRef, keyAlg, keySizeInBits, 0, pubKeyUse, pubKeyAttrs, privKeyUse, privKeyAttrs, access, &pubKeyRef, &privKeyRef);
+
+ if (!ortn)
+ ortn = SecKeyGetCSSMKey(pubKeyRef, &pubKey);
+ if (!ortn)
+ ortn = SecKeyGetCSSMKey(privKeyRef, &privKey);
+#else
ortn = generateKeyPair(cspHand,
dlDbHand,
keyAlg,
verbose,
&pubKey,
&privKey);
+#endif /* SEC_KEY_CREATE_PAIR */
if(ortn) {
printf("Error generating keys; aborting.\n");
goto abort;
}
abort:
/* CLEANUP */
+#if SEC_KEY_CREATE_PAIR
+ if (description) CFRelease(description);
+ if (access) CFRelease(access);
+ if (acls) CFRelease(acls);
+ if (pubKeyRef) CFRelease(pubKeyRef);
+ if (privKeyRef) CFRelease(privKeyRef);
+#endif /* SEC_KEY_CREATE_PAIR */
return 0;
}
void addApplication(TrustedApplication *app);
CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR &promptSelector()
- { assert(form() == appListForm); return mPromptSelector; }
+ { assert(form() == appListForm || form() == allowAllForm); return mPromptSelector; }
string &promptDescription()
- { assert(form() == appListForm); return mPromptDescription; }
+ { assert(form() == appListForm || form() == allowAllForm); return mPromptDescription; }
CSSM_ACL_HANDLE entryHandle() const { return mCssmHandle; }
using namespace KeychainCore;
+//
+// Create a completely open Access (anyone can do anything)
+// Note that this means anyone can *change* the ACL at will, too.
+// These ACL entries contain no descriptor names.
+//
+Access::Access()
+{
+ RefPointer<ACL> owner = new ACL(*this);
+ owner->setAuthorization(CSSM_ACL_AUTHORIZATION_CHANGE_ACL);
+ addOwner(owner);
+
+ RefPointer<ACL> any = new ACL(*this);
+ add(any);
+}
+
+
//
// Create a default Access object.
// This construct an Access with "default form", whatever that happens to be
makeStandard(descriptor, trusted);
}
-void Access::makeStandard(const string &descriptor, const ACL::ApplicationList &trusted)
+Access::Access(const string &descriptor, const ACL::ApplicationList &trusted,
+ const AclAuthorizationSet &limitedRights, const AclAuthorizationSet &freeRights)
+{
+ makeStandard(descriptor, trusted, limitedRights, freeRights);
+}
+
+void Access::makeStandard(const string &descriptor, const ACL::ApplicationList &trusted,
+ const AclAuthorizationSet &limitedRights, const AclAuthorizationSet &freeRights)
{
// owner "entry"
RefPointer<ACL> owner = new ACL(*this, descriptor, ACL::defaultSelector);
owner->setAuthorization(CSSM_ACL_AUTHORIZATION_CHANGE_ACL);
addOwner(owner);
- // encrypt entry
- RefPointer<ACL> encrypt = new ACL(*this, descriptor, ACL::defaultSelector);
- encrypt->setAuthorization(CSSM_ACL_AUTHORIZATION_ENCRYPT);
- encrypt->form(ACL::allowAllForm);
- add(encrypt);
-
- // decrypt entry
- RefPointer<ACL> decrypt = new ACL(*this, descriptor, ACL::defaultSelector);
- decrypt->setAuthorization(CSSM_ACL_AUTHORIZATION_DECRYPT);
- decrypt->applications() = trusted;
- add(decrypt);
+ // unlimited entry
+ RefPointer<ACL> unlimited = new ACL(*this, descriptor, ACL::defaultSelector);
+ if (freeRights.empty()) {
+ unlimited->authorizations().clear();
+ unlimited->authorizations().insert(CSSM_ACL_AUTHORIZATION_ENCRYPT);
+ } else
+ unlimited->authorizations() = freeRights;
+ unlimited->form(ACL::allowAllForm);
+ add(unlimited);
+
+ // limited entry
+ RefPointer<ACL> limited = new ACL(*this, descriptor, ACL::defaultSelector);
+ if (limitedRights.empty()) {
+ limited->authorizations().clear();
+ limited->authorizations().insert(CSSM_ACL_AUTHORIZATION_DECRYPT);
+ limited->authorizations().insert(CSSM_ACL_AUTHORIZATION_SIGN);
+ limited->authorizations().insert(CSSM_ACL_AUTHORIZATION_MAC);
+ limited->authorizations().insert(CSSM_ACL_AUTHORIZATION_DERIVE);
+ limited->authorizations().insert(CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR);
+ limited->authorizations().insert(CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED);
+ } else
+ limited->authorizations() = limitedRights;
+ limited->applications() = trusted;
+ add(limited);
}
{
list<ACL *> choices;
for (Map::const_iterator it = mAcls.begin(); it != mAcls.end(); it++)
- if (it->second->authorizations().find(action) != it->second->authorizations().end())
+ if (it->second->authorizes(action))
choices.push_back(it->second);
return choices.empty() ? NULL : makeCFArray(gTypes().acl, choices);
}
// If update, skip any part marked unchanged. (If not update, skip
// any part marked deleted.)
//
-void Access::setAccess(AclBearer &target, bool update = false)
+void Access::setAccess(AclBearer &target, bool update /* = false */)
{
AclFactory factory;
editAccess(target, update, factory.promptCred());
}
+//
+// Retrieve the description from a randomly chosen ACL within this Access.
+// In the conventional case where all ACLs have the same descriptor, this
+// is deterministic. But you have been warned.
+//
+string Access::promptDescription() const
+{
+ for (Map::const_iterator it = mAcls.begin(); it != mAcls.end(); it++) {
+ ACL *acl = it->second;
+ switch (acl->form()) {
+ case ACL::allowAllForm:
+ case ACL::appListForm:
+ {
+ string descr = acl->promptDescription();
+ if (!descr.empty())
+ return descr;
+ }
+ default:
+ break;
+ }
+ }
+ // couldn't find suitable ACL (no description anywhere)
+ CssmError::throwMe(errSecACLNotSimple);
+}
+
+
//
// Add a new ACL to the resident set. The ACL must have been
// newly made for this Access.
};
public:
+ // make default forms
Access(const string &description);
Access(const string &description, const ACL::ApplicationList &trusted);
+ Access(const string &description, const ACL::ApplicationList &trusted,
+ const AclAuthorizationSet &limitedRights, const AclAuthorizationSet &freeRights);
+
+ // make a completely open Access (anyone can do anything)
+ Access();
+
+ // retrieve from an existing AclBearer
Access(AclBearer &source);
+
+ // make from CSSM layer information (presumably retrieved by caller)
Access(const CSSM_ACL_OWNER_PROTOTYPE &owner,
uint32 aclCount, const CSSM_ACL_ENTRY_INFO *acls);
+
virtual ~Access();
public:
void setAccess(AclBearer &target, bool update = false);
void setAccess(AclBearer &target, Maker &maker);
-
+
template <class Container>
void findAclsForRight(AclAuthorization right, Container &cont)
{
cont.push_back(it->second);
}
+ std::string promptDescription() const; // from any one of the ACLs contained
+
void addApplicationToRight(AclAuthorization right, TrustedApplication *app);
protected:
- void makeStandard(const string &description, const ACL::ApplicationList &trusted);
+ void makeStandard(const string &description, const ACL::ApplicationList &trusted,
+ const AclAuthorizationSet &limitedRights = AclAuthorizationSet(),
+ const AclAuthorizationSet &freeRights = AclAuthorizationSet());
void compile(const CSSM_ACL_OWNER_PROTOTYPE &owner,
uint32 aclCount, const CSSM_ACL_ENTRY_INFO *acls);
#include "Globals.h"
#include <Security/DLDBListCFPref.h>
#include <Security/SecCFTypes.h>
+//#include <Security/Keychain.h>
using namespace KeychainCore;
using namespace CssmClient;
const Keychain &inKeychain,
const Item &inItem)
{
+ debug("kcnotify", "dispatch event %d pid %d keychain %p item %p",
+ inEvent, inPid, &inKeychain, !!inItem ? &*inItem : NULL);
+
// Deal with events that we care about ourselves first.
if (inEvent == kSecDefaultChangedEvent)
globals().defaultKeychain.reload(true);
else if (inEvent == kSecKeychainListChangedEvent)
globals().storageManager.reload(true);
+ else if (inEvent == kSecDeleteEvent && inKeychain.get() && inItem.get())
+ inKeychain->didDeleteItem(inItem.get());
// Iterate through callbacks, looking for those registered for inEvent
const SecKeychainEventMask theMask = 1U << inEvent;
}
Item
-ItemImpl::copyTo(const Keychain &keychain, Access *newAccess = NULL)
+ItemImpl::copyTo(const Keychain &keychain, Access *newAccess /* = NULL */)
{
Item item(*this);
if (newAccess)
}
// inform anyone interested that we are doing this
+#if SENDACCESSNOTIFICATIONS
if (outData)
{
KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
}
+#endif
}
void
*length=itemData.length();
itemData.Length=0;
+#if SENDACCESSNOTIFICATIONS
KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
+#endif
}
}
getContent(NULL, &outData);
+#if SENDACCESSNOTIFICATIONS
//%%%<might> be done elsewhere, but here is good for now
KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
+#endif
}
SSGroup
ItemImpl::group()
{
SSGroup group;
- if (&*mUniqueId)
+ if (!!mUniqueId)
{
Db db(mKeychain->database());
if (useSecureStorage(db))
//
#include <Security/KeyItem.h>
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <Security/cssmtype.h>
+#include <Security/Access.h>
+#include <Security/Keychains.h>
+#include <Security/KeyItem.h>
+#include <Security/wrapkey.h>
+#include <Security/globals.h>
+
+// @@@ This needs to be shared.
+static CSSM_DB_NAME_ATTR(kSecKeyLabel, 6, "Label", 0, NULL, BLOB);
+static CSSM_DB_NAME_ATTR(kSecKeyPrintName, 1, "PrintName", 0, NULL, BLOB);
using namespace KeychainCore;
return *mKey;
}
+
+const AccessCredentials *
+KeyItem::getCredentials(
+ CSSM_ACL_AUTHORIZATION_TAG operation,
+ SecCredentialType credentialType)
+{
+ // @@@ Fix this to actually examine the ACL for this key and consider operation and do the right thing.
+ AclFactory factory;
+ switch (credentialType)
+ {
+ case kSecCredentialTypeDefault:
+ return globals().credentials();
+ case kSecCredentialTypeWithUI:
+ return factory.promptCred();
+ case kSecCredentialTypeNoUI:
+ return factory.nullCred();
+ default:
+ MacOSError::throwMe(paramErr);
+ }
+}
+
+void
+KeyItem::createPair(
+ Keychain keychain,
+ CSSM_ALGORITHMS algorithm,
+ uint32 keySizeInBits,
+ CSSM_CC_HANDLE contextHandle,
+ CSSM_KEYUSE publicKeyUsage,
+ uint32 publicKeyAttr,
+ CSSM_KEYUSE privateKeyUsage,
+ uint32 privateKeyAttr,
+ RefPointer<Access> initialAccess,
+ RefPointer<KeyItem> &outPublicKey,
+ RefPointer<KeyItem> &outPrivateKey)
+{
+ bool freeKeys = false;
+ bool deleteContext = false;
+
+ if (!keychain->database()->dl()->subserviceMask() & CSSM_SERVICE_CSP)
+ MacOSError::throwMe(errSecInvalidKeychain);
+
+ SSDb ssDb(safe_cast<SSDbImpl *>(&(*keychain->database())));
+ CssmClient::CSP csp(keychain->csp());
+ CssmClient::CSP appleCsp(gGuidAppleCSP);
+
+ // Generate a random label to use initially
+ CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
+ uint8 labelBytes[20];
+ CssmData label(labelBytes, sizeof(labelBytes));
+ random.generate(label, label.Length);
+
+ // Create a Access::Maker for the initial owner of the private key.
+ ResourceControlContext rcc;
+ memset(&rcc, 0, sizeof(rcc));
+ Access::Maker maker;
+ // @@@ Potentially provide a credential argument which allows us to generate keys in the csp. Currently the CSP let's anyone do this, but we might restrict this in the future, f.e. a smartcard could require out of band pin entry before a key can be generated.
+ maker.initialOwner(rcc);
+ // Create the cred we need to manipulate the keys until we actually set a new access control for them.
+ const AccessCredentials *cred = maker.cred();
+
+ CSSM_KEY publicCssmKey, privateCssmKey;
+ memset(&publicCssmKey, 0, sizeof(publicCssmKey));
+ memset(&privateCssmKey, 0, sizeof(privateCssmKey));
+
+ CSSM_CC_HANDLE ccHandle = 0;
+
+ try
+ {
+ CSSM_RETURN status;
+ if (contextHandle)
+ ccHandle = contextHandle;
+ else
+ {
+ status = CSSM_CSP_CreateKeyGenContext(csp->handle(), algorithm, keySizeInBits, NULL, NULL, NULL, NULL, NULL, &ccHandle);
+ if (status)
+ CssmError::throwMe(status);
+ deleteContext = true;
+ }
+
+ CSSM_DL_DB_HANDLE dldbHandle = ssDb->handle();
+ CSSM_DL_DB_HANDLE_PTR dldbHandlePtr = &dldbHandle;
+ CSSM_CONTEXT_ATTRIBUTE contextAttributes = { CSSM_ATTRIBUTE_DL_DB_HANDLE, sizeof(dldbHandle), { (char *)dldbHandlePtr } };
+ status = CSSM_UpdateContextAttributes(ccHandle, 1, &contextAttributes);
+ if (status)
+ CssmError::throwMe(status);
+
+ // Generate the keypair
+ status = CSSM_GenerateKeyPair(ccHandle, publicKeyUsage, publicKeyAttr, &label, &publicCssmKey, privateKeyUsage, privateKeyAttr, &label, &rcc, &privateCssmKey);
+ if (status)
+ CssmError::throwMe(status);
+ freeKeys = true;
+
+ // Find the keys we just generated in the DL to get SecKeyRef's to them
+ // so we can change the label to be the hash of the public key, and
+ // fix up other attributes.
+
+ // Look up public key in the DLDB.
+ DbAttributes pubDbAttributes;
+ DbUniqueRecord pubUniqueId;
+ SSDbCursor dbPubCursor(ssDb, 1);
+ dbPubCursor->recordType(CSSM_DL_DB_RECORD_PUBLIC_KEY);
+ dbPubCursor->add(CSSM_DB_EQUAL, kSecKeyLabel, label);
+ CssmClient::Key publicKey;
+ if (!dbPubCursor->nextKey(&pubDbAttributes, publicKey, pubUniqueId))
+ MacOSError::throwMe(errSecItemNotFound);
+
+ // Look up private key in the DLDB.
+ DbAttributes privDbAttributes;
+ DbUniqueRecord privUniqueId;
+ SSDbCursor dbPrivCursor(ssDb, 1);
+ dbPrivCursor->recordType(CSSM_DL_DB_RECORD_PRIVATE_KEY);
+ dbPrivCursor->add(CSSM_DB_EQUAL, kSecKeyLabel, label);
+ CssmClient::Key privateKey;
+ if (!dbPrivCursor->nextKey(&privDbAttributes, privateKey, privUniqueId))
+ MacOSError::throwMe(errSecItemNotFound);
+
+ // Convert reference public key to a raw key so we can use it
+ // in the appleCsp.
+ CssmClient::WrapKey wrap(csp, CSSM_ALGID_NONE);
+ wrap.cred(cred);
+ CssmClient::Key rawPubKey = wrap(publicKey);
+
+ // Calculate the hash of the public key using the appleCSP.
+ CssmClient::PassThrough passThrough(appleCsp);
+ void *outData;
+ CssmData *cssmData;
+
+ /* Given a CSSM_KEY_PTR in any format, obtain the SHA-1 hash of the
+ * associated key blob.
+ * Key is specified in CSSM_CSP_CreatePassThroughContext.
+ * Hash is allocated bythe CSP, in the App's memory, and returned
+ * in *outData. */
+ passThrough.key(rawPubKey);
+ passThrough(CSSM_APPLECSP_KEYDIGEST, NULL, &outData);
+ cssmData = reinterpret_cast<CssmData *>(outData);
+ CssmData &pubKeyHash = *cssmData;
+
+ std::string description(initialAccess->promptDescription());
+ // Set the label of the public key to the public key hash.
+ // Set the PrintName of the public key to the description in the acl.
+ pubDbAttributes.add(kSecKeyLabel, pubKeyHash);
+ pubDbAttributes.add(kSecKeyPrintName, description);
+ pubUniqueId->modify(CSSM_DL_DB_RECORD_PUBLIC_KEY, &pubDbAttributes, NULL, CSSM_DB_MODIFY_ATTRIBUTE_REPLACE);
+
+ // Set the label of the private key to the public key hash.
+ // Set the PrintName of the private key to the description in the acl.
+ privDbAttributes.add(kSecKeyLabel, pubKeyHash);
+ privDbAttributes.add(kSecKeyPrintName, description);
+ privUniqueId->modify(CSSM_DL_DB_RECORD_PRIVATE_KEY, &privDbAttributes, NULL, CSSM_DB_MODIFY_ATTRIBUTE_REPLACE);
+
+ // @@@ Not exception safe!
+ csp.allocator().free(cssmData->Data);
+ csp.allocator().free(cssmData);
+
+ // Finally fix the acl and owner of the private key to the specified access control settings.
+ initialAccess->setAccess(*privateKey, maker);
+
+ // Make the public key acl completely open
+ Access pubKeyAccess;
+ pubKeyAccess.setAccess(*publicKey, maker);
+
+ // Create keychain items which will represent the keys.
+ outPublicKey = safe_cast<KeyItem*>(&(*keychain->item(CSSM_DL_DB_RECORD_PUBLIC_KEY, pubUniqueId)));
+ outPrivateKey = safe_cast<KeyItem*>(&(*keychain->item(CSSM_DL_DB_RECORD_PRIVATE_KEY, privUniqueId)));
+ }
+ catch (...)
+ {
+ if (freeKeys)
+ {
+ // Delete the keys if something goes wrong so we don't end up with inaccesable keys in the database.
+ CSSM_FreeKey(csp->handle(), cred, &publicCssmKey, TRUE);
+ CSSM_FreeKey(csp->handle(), cred, &privateCssmKey, TRUE);
+ }
+
+ if (deleteContext)
+ CSSM_DeleteContext(ccHandle);
+
+ throw;
+ }
+
+ if (freeKeys)
+ {
+ CSSM_FreeKey(csp->handle(), NULL, &publicCssmKey, FALSE);
+ CSSM_FreeKey(csp->handle(), NULL, &privateCssmKey, FALSE);
+ }
+
+ if (deleteContext)
+ CSSM_DeleteContext(ccHandle);
+}
+
+void
+KeyItem::importPair(
+ Keychain keychain,
+ const CSSM_KEY &publicWrappedKey,
+ const CSSM_KEY &privateWrappedKey,
+ RefPointer<Access> initialAccess,
+ RefPointer<KeyItem> &outPublicKey,
+ RefPointer<KeyItem> &outPrivateKey)
+{
+ bool freePublicKey = false;
+ bool freePrivateKey = false;
+ bool deleteContext = false;
+
+ if (!keychain->database()->dl()->subserviceMask() & CSSM_SERVICE_CSP)
+ MacOSError::throwMe(errSecInvalidKeychain);
+
+ SSDb ssDb(safe_cast<SSDbImpl *>(&(*keychain->database())));
+ CssmClient::CSP csp(keychain->csp());
+ CssmClient::CSP appleCsp(gGuidAppleCSP);
+
+ // Create a Access::Maker for the initial owner of the private key.
+ ResourceControlContext rcc;
+ memset(&rcc, 0, sizeof(rcc));
+ Access::Maker maker;
+ // @@@ Potentially provide a credential argument which allows us to unwrap keys in the csp. Currently the CSP let's anyone do this, but we might restrict this in the future, f.e. a smartcard could require out of band pin entry before a key can be generated.
+ maker.initialOwner(rcc);
+ // Create the cred we need to manipulate the keys until we actually set a new access control for them.
+ const AccessCredentials *cred = maker.cred();
+
+ CSSM_KEY publicCssmKey, privateCssmKey;
+ memset(&publicCssmKey, 0, sizeof(publicCssmKey));
+ memset(&privateCssmKey, 0, sizeof(privateCssmKey));
+
+ CSSM_CC_HANDLE ccHandle = 0;
+
+ try
+ {
+ CSSM_RETURN status;
+
+ // Calculate the hash of the public key using the appleCSP.
+ CssmClient::PassThrough passThrough(appleCsp);
+ void *outData;
+ CssmData *cssmData;
+
+ /* Given a CSSM_KEY_PTR in any format, obtain the SHA-1 hash of the
+ * associated key blob.
+ * Key is specified in CSSM_CSP_CreatePassThroughContext.
+ * Hash is allocated bythe CSP, in the App's memory, and returned
+ * in *outData. */
+ passThrough.key(&publicWrappedKey);
+ passThrough(CSSM_APPLECSP_KEYDIGEST, NULL, &outData);
+ cssmData = reinterpret_cast<CssmData *>(outData);
+ CssmData &pubKeyHash = *cssmData;
+
+ status = CSSM_CSP_CreateSymmetricContext(csp->handle(), publicWrappedKey.KeyHeader.AlgorithmId, CSSM_ALGMODE_NONE, NULL, NULL, NULL, CSSM_PADDING_NONE, NULL, &ccHandle);
+ if (status)
+ CssmError::throwMe(status);
+ deleteContext = true;
+
+ CSSM_DL_DB_HANDLE dldbHandle = ssDb->handle();
+ CSSM_DL_DB_HANDLE_PTR dldbHandlePtr = &dldbHandle;
+ CSSM_CONTEXT_ATTRIBUTE contextAttributes = { CSSM_ATTRIBUTE_DL_DB_HANDLE, sizeof(dldbHandle), { (char *)dldbHandlePtr } };
+ status = CSSM_UpdateContextAttributes(ccHandle, 1, &contextAttributes);
+ if (status)
+ CssmError::throwMe(status);
+
+ // Unwrap the the keys
+ status = CSSM_UnwrapKey(
+ ccHandle,
+ NULL,
+ &publicWrappedKey,
+ publicWrappedKey.KeyHeader.KeyUsage,
+ publicWrappedKey.KeyHeader.KeyAttr,
+ &pubKeyHash,
+ &rcc,
+ &publicCssmKey,
+ NULL);
+ if (status)
+ CssmError::throwMe(status);
+ freePublicKey = true;
+
+ status = CSSM_UnwrapKey(
+ ccHandle,
+ NULL,
+ &privateWrappedKey,
+ privateWrappedKey.KeyHeader.KeyUsage,
+ privateWrappedKey.KeyHeader.KeyAttr,
+ &pubKeyHash,
+ &rcc,
+ &privateCssmKey,
+ NULL);
+
+ if (status)
+ CssmError::throwMe(status);
+
+ freePrivateKey = true;
+
+ // Find the keys we just generated in the DL to get SecKeyRef's to them
+ // so we can change the label to be the hash of the public key, and
+ // fix up other attributes.
+
+ // Look up public key in the DLDB.
+ DbAttributes pubDbAttributes;
+ DbUniqueRecord pubUniqueId;
+ SSDbCursor dbPubCursor(ssDb, 1);
+ dbPubCursor->recordType(CSSM_DL_DB_RECORD_PUBLIC_KEY);
+ dbPubCursor->add(CSSM_DB_EQUAL, kSecKeyLabel, pubKeyHash);
+ CssmClient::Key publicKey;
+ if (!dbPubCursor->nextKey(&pubDbAttributes, publicKey, pubUniqueId))
+ MacOSError::throwMe(errSecItemNotFound);
+
+ // Look up private key in the DLDB.
+ DbAttributes privDbAttributes;
+ DbUniqueRecord privUniqueId;
+ SSDbCursor dbPrivCursor(ssDb, 1);
+ dbPrivCursor->recordType(CSSM_DL_DB_RECORD_PRIVATE_KEY);
+ dbPrivCursor->add(CSSM_DB_EQUAL, kSecKeyLabel, pubKeyHash);
+ CssmClient::Key privateKey;
+ if (!dbPrivCursor->nextKey(&privDbAttributes, privateKey, privUniqueId))
+ MacOSError::throwMe(errSecItemNotFound);
+
+ // @@@ Not exception safe!
+ csp.allocator().free(cssmData->Data);
+ csp.allocator().free(cssmData);
+
+ std::string description(initialAccess->promptDescription());
+ // Set the label of the public key to the public key hash.
+ // Set the PrintName of the public key to the description in the acl.
+ pubDbAttributes.add(kSecKeyPrintName, description);
+ pubUniqueId->modify(CSSM_DL_DB_RECORD_PUBLIC_KEY, &pubDbAttributes, NULL, CSSM_DB_MODIFY_ATTRIBUTE_REPLACE);
+
+ // Set the label of the private key to the public key hash.
+ // Set the PrintName of the private key to the description in the acl.
+ privDbAttributes.add(kSecKeyPrintName, description);
+ privUniqueId->modify(CSSM_DL_DB_RECORD_PRIVATE_KEY, &privDbAttributes, NULL, CSSM_DB_MODIFY_ATTRIBUTE_REPLACE);
+
+ // Finally fix the acl and owner of the private key to the specified access control settings.
+ initialAccess->setAccess(*privateKey, maker);
+
+ // Make the public key acl completely open
+ Access pubKeyAccess;
+ pubKeyAccess.setAccess(*publicKey, maker);
+
+ // Create keychain items which will represent the keys.
+ outPublicKey = safe_cast<KeyItem*>(&(*keychain->item(CSSM_DL_DB_RECORD_PUBLIC_KEY, pubUniqueId)));
+ outPrivateKey = safe_cast<KeyItem*>(&(*keychain->item(CSSM_DL_DB_RECORD_PRIVATE_KEY, privUniqueId)));
+ }
+ catch (...)
+ {
+ if (freePublicKey)
+ CSSM_FreeKey(csp->handle(), cred, &publicCssmKey, TRUE);
+ if (freePrivateKey)
+ CSSM_FreeKey(csp->handle(), cred, &privateCssmKey, TRUE);
+
+ if (deleteContext)
+ CSSM_DeleteContext(ccHandle);
+
+ throw;
+ }
+
+ if (freePublicKey)
+ CSSM_FreeKey(csp->handle(), cred, &publicCssmKey, FALSE);
+ if (freePrivateKey)
+ CSSM_FreeKey(csp->handle(), cred, &privateCssmKey, FALSE);
+
+ if (deleteContext)
+ CSSM_DeleteContext(ccHandle);
+}
#define _SECURITY_KEYITEM_H_
#include <Security/Item.h>
+#include <Security/SecKeyPriv.h>
namespace Security
{
CssmClient::SSDbUniqueRecord ssDbUniqueRecord();
const CssmKey &cssmKey();
+ const AccessCredentials *getCredentials(
+ CSSM_ACL_AUTHORIZATION_TAG operation,
+ SecCredentialType credentialType);
+
+ static void createPair(
+ Keychain keychain,
+ CSSM_ALGORITHMS algorithm,
+ uint32 keySizeInBits,
+ CSSM_CC_HANDLE contextHandle,
+ CSSM_KEYUSE publicKeyUsage,
+ uint32 publicKeyAttr,
+ CSSM_KEYUSE privateKeyUsage,
+ uint32 privateKeyAttr,
+ RefPointer<Access> initialAccess,
+ RefPointer<KeyItem> &outPublicKey,
+ RefPointer<KeyItem> &outPrivateKey);
+
+ static void importPair(
+ Keychain keychain,
+ const CSSM_KEY &publicCssmKey,
+ const CSSM_KEY &privateCssmKey,
+ RefPointer<Access> initialAccess,
+ RefPointer<KeyItem> &outPublicKey,
+ RefPointer<KeyItem> &outPrivateKey);
+
protected:
virtual PrimaryKey add(Keychain &keychain);
private:
mDbItemMap.insert(DbItemMap::value_type(primaryKey, dbItemImpl));
}
+void
+KeychainImpl::didDeleteItem(const ItemImpl *inItemImpl)
+{
+ // Sent sent by CCallbackMgr.
+ debug("kcnotify", "%p notified that item %p was deleted", this, inItemImpl);
+ PrimaryKey primaryKey = inItemImpl->primaryKey();
+ StLock<Mutex> _(mDbItemMapLock);
+ DbItemMap::iterator it = mDbItemMap.find(primaryKey);
+ if (it != mDbItemMap.end())
+ mDbItemMap.erase(it);
+}
+
void
KeychainImpl::removeItem(const PrimaryKey &primaryKey, const ItemImpl *inItemImpl)
{
void getAttributeInfoForItemID(CSSM_DB_RECORDTYPE itemID, SecKeychainAttributeInfo **Info);
static void freeAttributeInfo(SecKeychainAttributeInfo *Info);
KeychainSchema keychainSchema();
+ void didDeleteItem(const ItemImpl *inItemImpl);
private:
void addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl);
#include "SecBridge.h"
+#include <Security/Access.h>
+#include <Security/Keychains.h>
+#include <Security/KeyItem.h>
+
CFTypeID
SecKeyGetTypeID(void)
{
END_SECAPI1(_kCFRuntimeNotATypeID)
}
-
OSStatus
SecKeyCreatePair(
- SecKeychainRef keychain,
+ SecKeychainRef keychainRef,
CSSM_ALGORITHMS algorithm,
- UInt32 keySizeInBits,
- CSSM_KEYUSE publicKeyUsage,
- uint32 publicKeyAttr,
- SecKeychainItemRef* publicKeyItemRef,
- CSSM_KEYUSE privateKeyUsage,
- uint32 privateKeyAttr,
- SecKeychainItemRef* privateKeyItemRef,
- SecAccessRef initialAccess)
+ uint32 keySizeInBits,
+ CSSM_CC_HANDLE contextHandle,
+ CSSM_KEYUSE publicKeyUsage,
+ uint32 publicKeyAttr,
+ CSSM_KEYUSE privateKeyUsage,
+ uint32 privateKeyAttr,
+ SecAccessRef initialAccess,
+ SecKeyRef* publicKeyRef,
+ SecKeyRef* privateKeyRef)
{
BEGIN_SECAPI
- MacOSError::throwMe(unimpErr);//%%%for now
+ Keychain keychain = Keychain::optional(keychainRef);
+ RefPointer<Access> theAccess(initialAccess ? gTypes().access.required(initialAccess) : new Access("<key>"));
+ RefPointer<KeyItem> pubItem, privItem;
+
+ KeyItem::createPair(keychain,
+ algorithm,
+ keySizeInBits,
+ contextHandle,
+ publicKeyUsage,
+ publicKeyAttr,
+ privateKeyUsage,
+ privateKeyAttr,
+ theAccess,
+ pubItem,
+ privItem);
+
+ // Return the generated keys.
+ if (publicKeyRef)
+ *publicKeyRef = gTypes().keyItem.handle(*pubItem);
+ if (privateKeyRef)
+ *privateKeyRef = gTypes().keyItem.handle(*privItem);
END_SECAPI
}
END_SECAPI
}
+
+
+//
+// Private APIs
+//
+
+OSStatus
+SecKeyGetCredentials(
+ SecKeyRef keyRef,
+ CSSM_ACL_AUTHORIZATION_TAG operation,
+ SecCredentialType credentialType,
+ const CSSM_ACCESS_CREDENTIALS **outCredentials)
+{
+ BEGIN_SECAPI
+
+ RefPointer<KeyItem> keyItem(gTypes().keyItem.required(keyRef));
+ Required(outCredentials) = keyItem->getCredentials(operation, credentialType);
+
+ END_SECAPI
+}
+
+OSStatus
+SecKeyImportPair(
+ SecKeychainRef keychainRef,
+ const CssmKey *publicCssmKey,
+ const CssmKey *privateCssmKey,
+ SecAccessRef initialAccess,
+ SecKeyRef* publicKeyRef,
+ SecKeyRef* privateKeyRef)
+{
+ BEGIN_SECAPI
+
+ Keychain keychain = Keychain::optional(keychainRef);
+ RefPointer<Access> theAccess(initialAccess ? gTypes().access.required(initialAccess) : new Access("<key>"));
+ RefPointer<KeyItem> pubItem, privItem;
+
+ KeyItem::importPair(keychain,
+ Required(publicCssmKey),
+ Required(privateCssmKey),
+ theAccess,
+ pubItem,
+ privItem);
+
+ // Return the generated keys.
+ if (publicKeyRef)
+ *publicKeyRef = gTypes().keyItem.handle(*pubItem);
+ if (privateKeyRef)
+ *privateKeyRef = gTypes().keyItem.handle(*privItem);
+
+ END_SECAPI
+}
/*!
@function SecKeyCreatePair
@abstract Creates an asymmetric key pair and stores it in the keychain specified by the keychain parameter.
- @param keychain A reference to the keychain in which to store the private and public key items. Specify NULL for the default keychain.
- @param algorithm An algorithm for the key pair.
- @param keySizeInBits A key size for the key pair.
- @param publicKeyUsage A bit mask indicating all permitted uses for the new public key. The bit mask values are defined in cssmtype.h
+ @param keychainRef A reference to the keychain in which to store the private and public key items. Specify NULL for the default keychain.
+ @param algorithm An algorithm for the key pair. This parameter is ignored if contextHandle is non 0.
+ @param keySizeInBits A key size for the key pair. This parameter is ignored if contextHandle is non 0.
+ @param contextHandle An optional CSSM_CC_HANDLE or 0. If this argument is not 0 the algorithm and keySizeInBits parameters are ignored. If extra parameters are need to generate a key (some algortihms require this) you should create a context using CSSM_CSP_CreateKeyGenContext(), using the CSPHandle obtained by calling SecKeychainGetCSPHandle(). Then use CSSM_UpdateContextAttributes() to add additional parameters and dispose of the context using CSSM_DeleteContext after calling this function.
+ @param publicKeyUsage A bit mask indicating all permitted uses for the new public key. The bit mask values are defined in cssmtype.h
@param publicKeyAttr A bit mask defining attribute values for the new public key. The bit mask values are equivalent to a CSSM_KEYATTR_FLAGS and are defined in cssmtype.h
- @param publicKey A pointer to the keychain item reference of the new public key. Use the SecKeyGetCSSMKey function to obtain the CSSM_KEY. The public key item must be of class type kSecAppleKeyItemClass.
@param privateKeyUsage A bit mask indicating all permitted uses for the new private key. The bit mask values are defined in cssmtype.h
@param privateKeyAttr A bit mask defining attribute values for the new private key. The bit mask values are equivalent to a CSSM_KEYATTR_FLAGS and are defined in cssmtype.h
- @param privateKey A pointer to the keychain item reference of the new private key. Use the SecKeyGetCSSMKey function to obtain the CSSM_KEY. The private key item must be of class type kSecAppleKeyItemClass.
- @param initialAccess A reference to an initial access to use for each of the keys returned.
+ @param initialAccess A SecAccess object that determines the initial access rights to the private key. The public key is given an any/any acl by default.
+ @param publicKey Optional output pointer to the keychain item reference of the imported public key. Use the SecKeyGetCSSMKey function to obtain the CSSM_KEY. The caller must call CFRelease on this value if it is returned.
+ @param privateKey Optional output pointer to the keychain item reference of the imported private key. Use the SecKeyGetCSSMKey function to obtain the CSSM_KEY. The caller must call CFRelease on this value if it is returned.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
OSStatus SecKeyCreatePair(
- SecKeychainRef keychain,
+ SecKeychainRef keychainRef,
CSSM_ALGORITHMS algorithm,
uint32 keySizeInBits,
- CSSM_KEYUSE publicKeyUsage,
- uint32 publicKeyAttr,
+ CSSM_CC_HANDLE contextHandle,
+ CSSM_KEYUSE publicKeyUsage,
+ uint32 publicKeyAttr,
+ CSSM_KEYUSE privateKeyUsage,
+ uint32 privateKeyAttr,
+ SecAccessRef initialAccess,
SecKeyRef* publicKey,
- CSSM_KEYUSE privateKeyUsage,
- uint32 privateKeyAttr,
- SecKeyRef* privateKey,
- SecAccessRef initialAccess);
+ SecKeyRef* privateKey);
/*!
@function SecKeyGetCSSMKey
--- /dev/null
+/*
+ * SecKeyPriv.h
+ * Security
+ *
+ * Created by Michael Brouwer on Fri Nov 08 2002.
+ * Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+/*!
+ @header SecKeyPriv
+ The functions provided in SecKeyPriv implement a particular type of SecKeychainItem which represents a key. SecKeys might be stored in a SecKeychain, but can also be used as transient object representing keys.
+
+ Most SecKeychainItem* functions will work on an SecKeyRef.
+*/
+
+#ifndef _SECURITY_SECKEYPRIV_H_
+#define _SECURITY_SECKEYPRIV_H_
+
+#include <Security/SecKey.h>
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ @typedef SecCredentialType
+ @abstract Determines the type of credential returned by SecKeyGetCredentials.
+*/
+typedef uint32 SecCredentialType;
+
+/*!
+ @enum SecCredentialType
+ @abstract Determines the type of credential returned by SecKeyGetCredentials.
+ @constant kSecCredentialTypeWithUI will cause UI to happen if needed.
+ @constant kSecCredentialTypeNoUI will fail if UI would of been required.
+ @constant kSecCredentialTypeDefault will choose to do UI when other SecKeychain calls currently do.
+*/
+enum
+{
+ kSecCredentialTypeDefault = 0,
+ kSecCredentialTypeWithUI,
+ kSecCredentialTypeNoUI
+};
+
+
+/*!
+ @function SecKeyGetCredentials
+ @abstract For a given key return a const CSSM_ACCESS_CREDENTIALS * which will allow the key to be used.
+ @param keyRef The key for which a credential is requested.
+ @param operation the type of operation which is going to be perform on this key. Examples are: CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_DECRYPT, CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED.
+ @param credentialType The type of credential requested.
+ @param outCredentials Output a pointer to a const CSSM_ACCESS_CREDENTIALS * is returned here which remains valid at least as long as the keyRef itself remains valid, which can be used in CDSA calls.
+ @result A result code. See "Security Error Codes" (SecBase.h).
+*/
+OSStatus SecKeyGetCredentials(
+ SecKeyRef keyRef,
+ CSSM_ACL_AUTHORIZATION_TAG operation,
+ SecCredentialType credentialType,
+ const CSSM_ACCESS_CREDENTIALS **outCredentials);
+
+/*!
+ @function SecKeyImportPair
+ @abstract Takes an asymmetric key pair and stores it in the keychain specified by the keychain parameter.
+ @param keychainRef A reference to the keychain in which to store the private and public key items. Specify NULL for the default keychain.
+ @param publicCssmKey A CSSM_KEY which is valid for the CSP returned by SecKeychainGetCSPHandle(). This may be a normal key or reference key.
+ @param privateCssmKey A CSSM_KEY which is valid for the CSP returned by SecKeychainGetCSPHandle(). This may be a normal key or reference key.
+ @param initialAccess A SecAccess object that determines the initial access rights to the private key. The public key is given an any/any acl by default.
+ @param publicKey Optional output pointer to the keychain item reference of the imported public key. The caller must call CFRelease on this value if it is returned.
+ @param privateKey Optional output pointer to the keychain item reference of the imported private key. The caller must call CFRelease on this value if it is returned.
+ @result A result code. See "Security Error Codes" (SecBase.h).
+*/
+OSStatus SecKeyImportPair(
+ SecKeychainRef keychainRef,
+ const CSSM_KEY *publicCssmKey,
+ const CSSM_KEY *privateCssmKey,
+ SecAccessRef initialAccess,
+ SecKeyRef* publicKey,
+ SecKeyRef* privateKey);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_SECKEYPRIV_H_ */
+
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:58 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: SecureTransport
ProjectVersion: 3
+++ /dev/null
-LICENSE.txt\r-----------\rSSLRef 3.0 Final -- 11/19/96\rCopyright (c)1996 by Netscape Communications Corp.\r\rBy retrieving this software you are bound by the licensing terms\rdisclosed in the file "LICENSE.txt". Please read it, and if you\rdon't accept the terms, delete this software.\r\rSSLRef 3.0 was codeveloped by Netscape Communications Corp. of\rMountain View, California <http://home.netscape.com/> and Consensus\rDevelopment Corporation of Berkeley, California\r<http://www.consensus.com/>.\r\r\rSSL Reference Implemenation License Agreement for Non-Commercial Use\r--------------------------------------------------------------------\rNetscape Communications Corporation ("Netscape") hereby grants you a\rnon-exclusive, non-transferable license to use the Secure Sockets\rLayer Reference Implementation 3.0 (the "Software") subject to the\rfollowing terms:\r\r1. You may modify the Software and/or incorporate it, in whole or\rin part, into other software programs (a "Derivative Work").\r\r2. You may not use the Software or Derivative Works for\rrevenue-generating purposes. You may not:\r\r(a) license or distribute the Software or any Derivative Work in\rany manner that generates license fees, royalties, maintenance fees,\rupgrade fees or any other form of income.\r\r(b) use the Software or a Derivative Work to provide services to\rothers for which you are compensated in any manner.\r\r(c) distribute the Software or a Derivative Work without written\ragreement from the end user to abide by the terms of this Section 2.\r\r3. You may reproduce and use the Software and Derivative Works\rfree of charge for internal use. Such internal use may be at the\rpremises of an establishment which is engaged in revenue-generating\ractivities, provided that the Software and Derivative Works are not\rused as specified in Section 2.\r\r4. Any modification of the Software must prominently state in the\rmodified product or associated documentation that it has been\rmodified and the date the modifications were made. Any copy of the\rSoftware or Derivative Work shall include a copy of this Agreement,\rNetscape's copyright notices and the disclaimer of warranty and\rlimitation of liability.\r\r5. Title, ownership rights, and intellectual property rights in and\rto the Software shall remain in Netscape and/or its suppliers.\rYou may use the Software only as provided in this Agreement.\rNetscape shall have no obligation to provide maintenance, support,\rupgrades or new releases to you or any person to whom you distribute\rthe Software or a Derivative Work.\r\r6. Netscape may use Licensee's name in publicity materials as a\rlicensee of the Software.\r\r7. Disclaimer of Warranty. THE SOFTWARE IS LICENSED "AS IS"\rWITHOUT WARRANTY OF ANY KIND, INCLUDING WITHOUT LIMITATION,\rPERFORMANCE, MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR\rPURPOSE. THE ENTIRE RISK AS TO THE RESULTS AND PERFORMANCE OF THE\rSOFTWARE IS ASSUMED BY YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE,\rYOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR\rCORRECTION.\r\r8. Limitation of Liability. UNDER NO CIRCUMSTANCES AND UNDER NO\rLEGAL THEORY SHALL NETSCAPE OR ITS SUPPLIERS BE LIABLE TO YOU OR ANY\rOTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL\rDAMAGES OF ANY CHARACTER INCLUDING WITHOUT LIMITATION ANY COMMERCIAL\rDAMAGES OR LOSSES , EVEN IF NETSCAPE HAS BEEN INFORMED OF THE\rPOSSIBILITY OF SUCH DAMAGES.\r\r9. You may not download or otherwise export or reexport the\rSoftware or any underlying information or technology except in full\rcompliance with all United States and other applicable laws and\rregulations. EXCEPT FOR EXPORT TO CANADA FOR USE IN CANADA BY\rCANADIAN CITIZENS, THE SOFTWARE AND ANY UNDERLYING TECHNOLOGY MAY\rNOT BE EXPORTED OUTSIDE THE UNITED STATES OR TO ANY FOREIGN ENTITY\rOR "FOREIGN PERSON" AS DEFINED BY U.S. GOVERNMENT REGULATIONS,\rINCLUDING WITHOUT LIMITATION, ANYONE WHO IS NOT A CITIZEN, NATIONAL\rOR LAWFUL PERMANENT RESIDENT OF THE UNITED STATES. BY DOWNLOADING\rOR USING THE SOFTWARE, YOU ARE AGREEING TO THE FOREGOING AND YOU ARE\rWARRANTING THAT YOU ARE NOT A "FOREIGN PERSON" OR UNDER THE CONTROL\rOF A FOREIGN PERSON.\r\r10. Either party may terminate this Agreement immediately in the\revent of default by the other party. You may also terminate this\rAgreement at any time by destroying the Software and all copies\rthereof. Termination of your license will not terminate any\rsublicenses previously granted by you so long as the sublicensee\rcomplies with this Agreement.\r\r11. Use, duplication or disclosure by the United States Government\ris subject to restrictions set forth in subparagraphs (a) through\r(d) of the Commercial Computer-Restricted Rights clause at FAR\r52.227-19 when applicable, or in subparagraph (c)(1)(ii) of the\rRights in Technical Data and Computer Program clause at DFARS\r252.227-7013, and in similar clauses in the NASA FAR Supplement.\rContractor/manufacturer is Netscape Communications Corporation, 501\rEast Middlefield Road, Mountain View, CA 94043.\r\r12. This Agreement shall be governed by and construed under\rCalifornia law as such law applies to agreements between California\rresidents entered into and to be performed entirely within\rCalifornia, except as governed by Federal law.\r
\ No newline at end of file
mCspHand(CSSM_INVALID_HANDLE),
mClHand(CSSM_INVALID_HANDLE),
mTpHand(CSSM_INVALID_HANDLE),
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- mCspDlHand(CSSM_INVALID_HANDLE),
- #endif
mCssmInitd(false)
{ }
~ModuleAttacher();
CSSM_RETURN loadAllModules(
CSSM_CSP_HANDLE &cspHand,
CSSM_CL_HANDLE &clHand,
- CSSM_TP_HANDLE &tpHand
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- ,
- CSSM_CSP_HANDLE &cspDlHand
- #endif
- );
+ CSSM_TP_HANDLE &tpHand);
private:
/* on all private member functions, mLock held on entry and exit */
CSSM_CSP_HANDLE mCspHand;
CSSM_TP_HANDLE mClHand;
CSSM_TP_HANDLE mTpHand;
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- CSSM_CSP_HANDLE mCspDlHand;
- #endif
bool mCssmInitd;
Mutex mLock;
};
if(mClHand != CSSM_INVALID_HANDLE) {
unloadModule(mClHand, &gGuidAppleX509CL);
}
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- if(mCspDlHand != CSSM_INVALID_HANDLE) {
- unloadModule(mCspDlHand, &gGuidAppleCSPDL);
- }
- #endif
}
static const CSSM_VERSION cssmVers = {2, 0};
&pvcPolicy,
NULL /* reserved */);
if(crtn != CSSM_OK) {
- errorLog1("CSSM_Init returned %s", stCssmErrToStr(crtn));
+ #ifndef NDEBUG
+ sslErrorLog("CSSM_Init returned %s", stCssmErrToStr(crtn));
+ #endif
return false;
}
else {
NULL, // eventHandler
NULL); // AppNotifyCallbackCtx
if(crtn) {
- errorLog2("ModuleAttacher::loadModule: error (%s) loading %s\n",
+ #ifndef NDEBUG
+ sslErrorLog("ModuleAttacher::loadModule: error (%s) loading %s\n",
stCssmErrToStr(crtn), modName);
+ #endif
return CSSM_INVALID_HANDLE;
}
crtn = CSSM_ModuleAttach (guid,
NULL, // reserved
&hand);
if(crtn) {
- errorLog2("ModuleAttacher::loadModule: error (%s) attaching to %s\n",
+ #ifndef NDEBUG
+ sslErrorLog("ModuleAttacher::loadModule: error (%s) attaching to %s\n",
stCssmErrToStr(crtn), modName);
+ #endif
return CSSM_INVALID_HANDLE;
}
return hand;
CSSM_RETURN ModuleAttacher::loadAllModules(
CSSM_CSP_HANDLE &cspHand,
CSSM_CL_HANDLE &clHand,
- CSSM_TP_HANDLE &tpHand
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- ,
- CSSM_CSP_HANDLE &cspDlHand
- #endif
- )
+ CSSM_TP_HANDLE &tpHand)
{
StLock<Mutex> _(mLock);
return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
}
}
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- if(mCspDlHand == CSSM_INVALID_HANDLE) {
- mCspDlHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSPDL, "AppleCSPDL");
- if(mCspDlHand == CSSM_INVALID_HANDLE) {
- return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
- }
- }
- cspDlHand = mCspDlHand;
- #endif
cspHand = mCspHand;
clHand = mClHand;
tpHand = mTpHand;
CSSM_RETURN attachToModules(
CSSM_CSP_HANDLE *cspHand,
CSSM_CL_HANDLE *clHand,
- CSSM_TP_HANDLE *tpHand
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- ,
- CSSM_CSP_HANDLE *cspDlHand
- #endif
- )
+ CSSM_TP_HANDLE *tpHand)
{
- return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- ,
- *cspDlHand
- #endif
- );
+ return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand);
}
extern CSSM_RETURN attachToModules(
CSSM_CSP_HANDLE *cspHand,
CSSM_CL_HANDLE *clHand,
- CSSM_TP_HANDLE *tpHand
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- ,
- /* manually attach to secure CSP/DL; eventually we get this from
- * SecKeychainAPI */
- CSSM_CSP_HANDLE *cspDlHandle
- #endif
- );
+ CSSM_TP_HANDLE *tpHand);
#ifdef __cplusplus
}
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/privateInc\"";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
OPTIMIZATION_CFLAGS = "-O3";
- OTHER_CFLAGS = "";
+ OTHER_CFLAGS = "-DNDEBUG";
OTHER_LDFLAGS = "-lstdc++";
OTHER_LIBTOOL_FLAGS = "";
OTHER_REZFLAGS = "";
productName = SecureTransport;
productReference = 00E4CE36FF9B8CA8D0A17CE7;
productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
-<plist version=\"0.9\">
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
buildActionMask = 2147483647;
files = (
00E4CE62FF9B8EABD0A17CE7,
- 00E4CE63FF9B8EABD0A17CE7,
00E4CE64FF9B8EABD0A17CE7,
00E4CE65FF9B8EABD0A17CE7,
00E4CE66FF9B8EABD0A17CE7,
00E4CE71FF9B8EABD0A17CE7,
00E4CE72FF9B8EABD0A17CE7,
00E4CE73FF9B8EABD0A17CE7,
- 00E4CE75FF9B8EABD0A17CE7,
00E4CE76FF9B8EABD0A17CE7,
00E4CE77FF9B8EABD0A17CE7,
00E4CE78FF9B8EABD0A17CE7,
00E4CE79FF9B8EABD0A17CE7,
00E4CE7AFF9B8EABD0A17CE7,
- 00E4CE7BFF9B8EABD0A17CE7,
00E4CE7CFF9B8EABD0A17CE7,
00E4CE7DFF9B8EABD0A17CE7,
00E4CEB7FF9B909FD0A17CE7,
9D1B441A01F5ED1200003D05,
9D1B441B01F5ED1200003D05,
9D1B441C01F5ED1200003D05,
+ 9DD49D9A030C714000003D05,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
00E4CE3AFF9B8CA8D0A17CE7 = {
buildActionMask = 2147483647;
9D1B442001F5ED1200003D05,
);
isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
00E4CE3BFF9B8CA8D0A17CE7 = {
buildActionMask = 2147483647;
files = (
00E4CE82FF9B8F1DD0A17CE7,
- 00E4CE83FF9B8F1DD0A17CE7,
00E4CE85FF9B8F1DD0A17CE7,
00E4CE9BFF9B8FE5D0A17CE7,
00E4CE9EFF9B8FE5D0A17CE7,
00E4CEAAFF9B8FE5D0A17CE7,
00E4CEABFF9B8FE5D0A17CE7,
00E4CEACFF9B8FE5D0A17CE7,
- 00E4CEADFF9B8FE5D0A17CE7,
00E4CEAEFF9B8FE5D0A17CE7,
00E4CEAFFF9B8FE5D0A17CE7,
00E4CEB9FF9B909FD0A17CE7,
00E4CEBCFF9B909FD0A17CE7,
00E4CEBDFF9B909FD0A17CE7,
00E4CEC0FF9B9A4ED0A17CE7,
- 00E4CEC2FF9BA51FD0A17CE7,
0145E21EFFEED50A7F000001,
9D1B442601F5ED3000003D05,
9D1B442701F5ED3000003D05,
9D1B443101F5EE8D00003D05,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
00E4CE3CFF9B8CA8D0A17CE7 = {
buildActionMask = 2147483647;
9D1B442C01F5ED9400003D05,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
00E4CE3DFF9B8CA8D0A17CE7 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
00E4CE3EFF9B8E08D0A17CE7 = {
children = (
00E4CE8BFF9B8FE5D0A17CE7,
00E4CE8CFF9B8FE5D0A17CE7,
00E4CE8DFF9B8FE5D0A17CE7,
- 00E4CE8EFF9B8FE5D0A17CE7,
00E4CE8FFF9B8FE5D0A17CE7,
00E4CE90FF9B8FE5D0A17CE7,
);
00E4CE42FF9B8EABD0A17CE7 = {
children = (
00E4CE43FF9B8EABD0A17CE7,
- 00E4CE44FF9B8EABD0A17CE7,
00E4CE45FF9B8EABD0A17CE7,
00E4CE46FF9B8EABD0A17CE7,
00E4CE47FF9B8EABD0A17CE7,
00E4CE52FF9B8EABD0A17CE7,
00E4CE53FF9B8EABD0A17CE7,
00E4CE54FF9B8EABD0A17CE7,
- 00E4CE56FF9B8EABD0A17CE7,
00E4CE57FF9B8EABD0A17CE7,
00E4CE58FF9B8EABD0A17CE7,
00E4CE59FF9B8EABD0A17CE7,
00E4CE5AFF9B8EABD0A17CE7,
00E4CE5BFF9B8EABD0A17CE7,
- 00E4CE5CFF9B8EABD0A17CE7,
00E4CE5DFF9B8EABD0A17CE7,
00E4CE5EFF9B8EABD0A17CE7,
9D1B441301F5ED1200003D05,
9D1B441801F5ED1200003D05,
9D1B441901F5ED1200003D05,
+ 9DD49D99030C714000003D05,
);
isa = PBXGroup;
name = "Private Headers";
path = privateInc/appleCdsa.h;
refType = 4;
};
- 00E4CE44FF9B8EABD0A17CE7 = {
- isa = PBXFileReference;
- name = appleGlue.h;
- path = privateInc/appleGlue.h;
- refType = 4;
- };
00E4CE45FF9B8EABD0A17CE7 = {
isa = PBXFileReference;
name = appleSession.h;
};
00E4CE48FF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = digests.h;
- path = privateInc/digests.h;
+ name = sslDigests.h;
+ path = privateInc/sslDigests.h;
refType = 4;
};
00E4CE4DFF9B8EABD0A17CE7 = {
};
00E4CE4FFF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = sslalert.h;
- path = privateInc/sslalert.h;
+ name = sslAlertMessage.h;
+ path = privateInc/sslAlertMessage.h;
refType = 4;
};
00E4CE50FF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = sslalloc.h;
- path = privateInc/sslalloc.h;
+ name = sslMemory.h;
+ path = privateInc/sslMemory.h;
refType = 4;
};
00E4CE51FF9B8EABD0A17CE7 = {
};
00E4CE53FF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = sslctx.h;
- path = privateInc/sslctx.h;
+ name = sslContext.h;
+ path = privateInc/sslContext.h;
refType = 4;
};
00E4CE54FF9B8EABD0A17CE7 = {
path = privateInc/sslDebug.h;
refType = 4;
};
- 00E4CE56FF9B8EABD0A17CE7 = {
- isa = PBXFileReference;
- name = sslerrs.h;
- path = privateInc/sslerrs.h;
- refType = 4;
- };
00E4CE57FF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = sslhdshk.h;
- path = privateInc/sslhdshk.h;
+ name = sslHandshake.h;
+ path = privateInc/sslHandshake.h;
refType = 4;
};
00E4CE58FF9B8EABD0A17CE7 = {
};
00E4CE5AFF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = sslrec.h;
- path = privateInc/sslrec.h;
+ name = sslRecord.h;
+ path = privateInc/sslRecord.h;
refType = 4;
};
00E4CE5BFF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = sslsess.h;
- path = privateInc/sslsess.h;
- refType = 4;
- };
- 00E4CE5CFF9B8EABD0A17CE7 = {
- isa = PBXFileReference;
- name = ssltrspt.h;
- path = privateInc/ssltrspt.h;
+ name = sslSession.h;
+ path = privateInc/sslSession.h;
refType = 4;
};
00E4CE5DFF9B8EABD0A17CE7 = {
isa = PBXFileReference;
- name = sslutil.h;
- path = privateInc/sslutil.h;
+ name = sslUtils.h;
+ path = privateInc/sslUtils.h;
refType = 4;
};
00E4CE5EFF9B8EABD0A17CE7 = {
00E4CE5FFF9B8EABD0A17CE7 = {
children = (
00E4CE7EFF9B8F1DD0A17CE7,
- 00E4CE7FFF9B8F1DD0A17CE7,
00E4CE81FF9B8F1DD0A17CE7,
00E4CE91FF9B8FE5D0A17CE7,
00E4CE94FF9B8FE5D0A17CE7,
- 00E4CEC1FF9BA51FD0A17CE7,
0145E21BFFEED50A7F000001,
9D1B442101F5ED3000003D05,
9D1B442201F5ED3000003D05,
);
};
};
- 00E4CE63FF9B8EABD0A17CE7 = {
- fileRef = 00E4CE44FF9B8EABD0A17CE7;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- Private,
- );
- };
- };
00E4CE64FF9B8EABD0A17CE7 = {
fileRef = 00E4CE45FF9B8EABD0A17CE7;
isa = PBXBuildFile;
);
};
};
- 00E4CE75FF9B8EABD0A17CE7 = {
- fileRef = 00E4CE56FF9B8EABD0A17CE7;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- Private,
- );
- };
- };
00E4CE76FF9B8EABD0A17CE7 = {
fileRef = 00E4CE57FF9B8EABD0A17CE7;
isa = PBXBuildFile;
);
};
};
- 00E4CE7BFF9B8EABD0A17CE7 = {
- fileRef = 00E4CE5CFF9B8EABD0A17CE7;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- Private,
- );
- };
- };
00E4CE7CFF9B8EABD0A17CE7 = {
fileRef = 00E4CE5DFF9B8EABD0A17CE7;
isa = PBXBuildFile;
};
00E4CE7EFF9B8F1DD0A17CE7 = {
isa = PBXFileReference;
- path = appleCdsa.c;
- refType = 4;
- };
- 00E4CE7FFF9B8F1DD0A17CE7 = {
- isa = PBXFileReference;
- path = appleGlue.c;
+ path = appleCdsa.cpp;
refType = 4;
};
00E4CE81FF9B8F1DD0A17CE7 = {
isa = PBXFileReference;
- path = sslKeychain.c;
+ path = sslKeychain.cpp;
refType = 4;
};
00E4CE82FF9B8F1DD0A17CE7 = {
);
};
};
- 00E4CE83FF9B8F1DD0A17CE7 = {
- fileRef = 00E4CE7FFF9B8F1DD0A17CE7;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- );
- };
- };
00E4CE85FF9B8F1DD0A17CE7 = {
fileRef = 00E4CE81FF9B8F1DD0A17CE7;
isa = PBXBuildFile;
};
00E4CE86FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = ssl2map.c;
+ path = ssl2CipherMap.cpp;
refType = 4;
};
00E4CE87FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = ssl2mesg.c;
+ path = ssl2Message.cpp;
refType = 4;
};
00E4CE88FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = ssl2prot.c;
+ path = ssl2Protocol.cpp;
refType = 4;
};
00E4CE89FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = ssl2rec.c;
+ path = ssl2Record.cpp;
refType = 4;
};
00E4CE8AFF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = hdskcert.c;
+ path = sslCert.cpp;
refType = 4;
};
00E4CE8BFF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = hdskchgc.c;
+ path = sslChangeCipher.cpp;
refType = 4;
};
00E4CE8CFF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = hdskfini.c;
+ path = sslHandshakeFinish.cpp;
refType = 4;
};
00E4CE8DFF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = hdskhelo.c;
- refType = 4;
- };
- 00E4CE8EFF9B8FE5D0A17CE7 = {
- isa = PBXFileReference;
- path = hdskkeys.c;
+ path = sslHandshakeHello.cpp;
refType = 4;
};
00E4CE8FFF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = hdskkyex.c;
+ path = sslKeyExchange.cpp;
refType = 4;
};
00E4CE90FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = sslhdshk.c;
+ path = sslHandshake.cpp;
refType = 4;
};
00E4CE91FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = cipherSpecs.c;
+ path = cipherSpecs.cpp;
refType = 4;
};
00E4CE94FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = symCipher.c;
+ path = symCipher.cpp;
refType = 4;
};
00E4CE95FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = digests.c;
+ path = sslDigests.cpp;
refType = 4;
};
00E4CE97FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = nullciph.c;
+ path = sslNullCipher.cpp;
refType = 4;
};
00E4CE99FF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = sslalloc.c;
+ path = sslMemory.cpp;
refType = 4;
};
00E4CE9AFF9B8FE5D0A17CE7 = {
isa = PBXFileReference;
- path = sslutil.c;
+ path = sslUtils.cpp;
refType = 4;
};
00E4CE9BFF9B8FE5D0A17CE7 = {
);
};
};
- 00E4CEADFF9B8FE5D0A17CE7 = {
- fileRef = 00E4CE8EFF9B8FE5D0A17CE7;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- );
- };
- };
00E4CEAEFF9B8FE5D0A17CE7 = {
fileRef = 00E4CE8FFF9B8FE5D0A17CE7;
isa = PBXBuildFile;
};
00E4CEB0FF9B909FD0A17CE7 = {
isa = PBXFileReference;
- path = sslalert.c;
+ path = sslAlertMessage.cpp;
refType = 4;
};
00E4CEB1FF9B909FD0A17CE7 = {
isa = PBXFileReference;
- path = sslctx.c;
+ path = sslContext.cpp;
refType = 4;
};
00E4CEB2FF9B909FD0A17CE7 = {
isa = PBXFileReference;
- path = sslrec.c;
+ path = sslRecord.cpp;
refType = 4;
};
00E4CEB3FF9B909FD0A17CE7 = {
isa = PBXFileReference;
- path = sslsess.c;
+ path = sslSession.cpp;
refType = 4;
};
00E4CEB4FF9B909FD0A17CE7 = {
isa = PBXFileReference;
- path = ssltrspt.c;
+ path = sslTransport.cpp;
refType = 4;
};
00E4CEB5FF9B909FD0A17CE7 = {
);
};
};
- 00E4CEC1FF9BA51FD0A17CE7 = {
- isa = PBXFileReference;
- path = cppUtils.cpp;
- refType = 4;
- };
- 00E4CEC2FF9BA51FD0A17CE7 = {
- fileRef = 00E4CEC1FF9BA51FD0A17CE7;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- );
- };
- };
//000
//001
//002
};
9D1B442301F5ED3000003D05 = {
isa = PBXFileReference;
- path = ssl3Callouts.c;
+ path = ssl3Callouts.cpp;
refType = 4;
};
9D1B442401F5ED3000003D05 = {
isa = PBXFileReference;
- path = tls_hmac.c;
+ path = tls_hmac.cpp;
refType = 4;
};
9D1B442501F5ED3000003D05 = {
isa = PBXFileReference;
- path = tls1Callouts.c;
+ path = tls1Callouts.cpp;
refType = 4;
};
9D1B442601F5ED3000003D05 = {
};
9D1B443001F5EE8D00003D05 = {
isa = PBXFileReference;
- path = sslBER_Dummy.c;
+ path = sslBER_Dummy.cpp;
refType = 4;
};
9D1B443101F5EE8D00003D05 = {
settings = {
};
};
+ 9DD49D99030C714000003D05 = {
+ isa = PBXFileReference;
+ name = SecureTransportPriv.h;
+ path = privateInc/SecureTransportPriv.h;
+ refType = 4;
+ };
+ 9DD49D9A030C714000003D05 = {
+ fileRef = 9DD49D99030C714000003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
};
rootObject = 00E4CE33FF9B8B71D0A17CE7;
}
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B,
SSL_FORTEZZA_DMS_WITH_NULL_SHA = 0x001C,
SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA = 0x001D,
- SSL_RSA_WITH_RC2_CBC_MD5 = 0xFF80, /* These are included to provide tags for */
- SSL_RSA_WITH_IDEA_CBC_MD5 = 0xFF81, /* SSL 2 cipher kinds which are not specified */
- SSL_RSA_WITH_DES_CBC_MD5 = 0xFF82, /* for SSL 3 */
+ /*
+ * Tags for SSL 2 cipher kinds which are not specified
+ * for SSL 3.
+ */
+ SSL_RSA_WITH_RC2_CBC_MD5 = 0xFF80,
+ SSL_RSA_WITH_IDEA_CBC_MD5 = 0xFF81,
+ SSL_RSA_WITH_DES_CBC_MD5 = 0xFF82,
SSL_RSA_WITH_3DES_EDE_CBC_MD5 = 0xFF83,
SSL_NO_SUCH_CIPHERSUITE = 0xFFFF
};
#ifndef _SECURITY_SECURETRANSPORT_H_
#define _SECURITY_SECURETRANSPORT_H_
-/* Current capabilities */
-#define ST_SERVER_MODE_ENABLE 1
-#define ST_CLIENT_AUTHENTICATION 0
-
/*
* This file describes the public API for an implementation of the
* Secure Socket Layer, V. 3.0, and Transport Layer Security, V. 1.0.
- * This implementation is based on Netscape's SSLRef 3.0, modified
- * for Apple use. (Appropriate copyrights and acknowledgements are
- * found elsewhere, and in all files containing Netscape code.)
*
- * As in SSLRef 3.0, there no transport layer dependencies in this library;
+ * There no transport layer dependencies in this library;
* it can be used with sockets, Open Transport, etc. Applications using
* this library provide callback functions which do the actual I/O
* on underlying network connections. Applications are also responsible
kSSLAborted /* connection aborted */
} SSLSessionState;
+/*
+ * Status of client certificate exchange (which is optional
+ * for both server and client).
+ */
+typedef enum {
+ /* Server hasn't asked for a cert. Client hasn't sent one. */
+ kSSLClientCertNone,
+ /* Server has asked for a cert, but client didn't send it. */
+ kSSLClientCertRequested,
+ /*
+ * Server side: We asked for a cert, client sent one, we validated
+ * it OK. App can inspect the cert via
+ * SSLGetPeerCertificates().
+ * Client side: server asked for one, we sent it.
+ */
+ kSSLClientCertSent,
+ /*
+ * Client sent a cert but failed validation. Server side only.
+ * Server app can inspect the cert via SSLGetPeerCertificates().
+ */
+ kSSLClientCertRejected
+} SSLClientCertificateState;
+
/*
* R/W functions. The application using this library provides
* these functions via SSLSetIOFuncs().
*
* The application may configure the underlying connection to operate
* in a non-blocking manner; in such a case, a read operation may
- * well return SSLWouldBlockErr, indicating "I transferred less data than
+ * well return errSSLWouldBlock, indicating "I transferred less data than
* you requested (maybe even zero bytes), nothing is wrong, except
* requested I/O hasn't completed". This will be returned back up to
* the application as a return from SSLRead(), SSLWrite(), SSLHandshake(),
SSLGetProtocolVersion (SSLContextRef context,
SSLProtocol *protocol); /* RETURNED */
-#if (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
-
/*
* Specify this connection's certificate(s). This is mandatory for
* server connections, optional for clients. Specifying a certificate
SSLSetCertificate (SSLContextRef context,
CFArrayRef certRefs);
-#endif /* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
-
/*
* Specify I/O connection - a socket, endpoint, etc., which is
* managed by caller. On the client side, it's assumed that communication
SSLCipherSuite *ciphers, /* RETURNED */
size_t *numCiphers); /* IN/OUT */
+/*
+ * Enable/disable peer certificate chain validation. Default is enabled.
+ * If caller disables, it is the caller's responsibility to call
+ * SSLGetPeerCertificates() upon successful completion of the handshake
+ * and then to perform external validation of the peer certificate
+ * chain before proceeding with data transfer.
+ */
+OSStatus
+SSLSetEnableCertVerify (SSLContextRef context,
+ Boolean enableVerify);
+
+OSStatus
+SSLGetEnableCertVerify (SSLContextRef context,
+ Boolean *enableVerify); /* RETURNED */
+
/*
* Specify the option of ignoring certificates' "expired" times.
SSLGetAllowsExpiredCerts (SSLContextRef context,
Boolean *allowsExpired); /* RETURNED */
+/*
+ * Similar to SSLSetAllowsExpiredCerts(), this function allows the
+ * option of ignoring "expired" status for root certificates only.
+ * Default is false, i.e., expired root certs result in an
+ * errSSLCertExpired error.
+ */
+OSStatus
+SSLSetAllowsExpiredRoots (SSLContextRef context,
+ Boolean allowsExpired);
+
+OSStatus
+SSLGetAllowsExpiredRoots (SSLContextRef context,
+ Boolean *allowsExpired); /* RETURNED */
+
/*
* Specify option of allowing for an unknown root cert, i.e., one which
* this software can not verify as one of a list of known good root certs.
SSLGetAllowsAnyRoot (SSLContextRef context,
Boolean *anyRoot); /* RETURNED */
+/*
+ * Augment or replace the system's default trusted root certificate set
+ * for this session. If replaceExisting is true, the specified roots will
+ * be the only roots which are trusted during this session. If replaceExisting
+ * is false, the specified roots will be added to the current set of trusted
+ * root certs. If this function has never been called, the current trusted
+ * root set is the same as the system's default trusted root set.
+ * Successive calls with replaceExisting false result in accumulation
+ * of additional root certs.
+ *
+ * The trustedRoots array contains SecCertificateRefs.
+ */
+OSStatus
+SSLSetTrustedRoots (SSLContextRef context,
+ CFArrayRef trustedRoots,
+ Boolean replaceExisting);
+
+/*
+ * Obtain an array of SecCertificateRefs representing the current
+ * set of trusted roots. If SSLSetTrustedRoots() has never been called
+ * for this session, this returns the system's default root set.
+ */
+OSStatus
+SSLGetTrustedRoots (SSLContextRef context,
+ CFArrayRef *trustedRoots); /* RETURNED */
+
/*
* Request peer certificates. Valid anytime, subsequent to
* a handshake attempt.
*** Session context configuration, server side only. ***
********************************************************/
-#if ST_SERVER_MODE_ENABLE
/*
* Specify this connection's encryption certificate(s). This is
* used in one of the following cases:
SSLSetClientSideAuthenticate (SSLContextRef context,
SSLAuthenticate auth);
-#endif /* ST_SERVER_MODE_ENABLE */
+/*
+ * Add a DER-encoded dinstiguished name to list of acceptable names
+ * to be specified in requests for client certificates.
+ */
+OSStatus
+SSLAddDistinguishedName (SSLContextRef context,
+ const void *derDN,
+ size_t derDNLen);
+
+/*
+ * Obtain client certificate exhange status. Can be called
+ * any time. Reflects the *last* client certificate state change;
+ * subsequent to a renegotiation attempt by either peer, the state
+ * is reset to kSSLClientCertNone.
+ */
+OSStatus
+SSLGetClientCertificateState (SSLContextRef context,
+ SSLClientCertificateState *clientState);
/*******************************
******** I/O Functions ********
/*
* Note: depending on the configuration of the underlying I/O
- * connection, all SSL I/O functions can return SSLWouldBlockErr,
+ * connection, all SSL I/O functions can return errSSLWouldBlock,
* indicating "not complete, nothing is wrong, except required
* I/O hasn't completed". Caller may need to repeat I/Os as necessary
* if the underlying connection has been configured to behave in
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: appleCdsa.c
-
- Contains: interface between SSL and CDSA
-
- Written by: Doug Mitchell
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-#include "ssl.h"
-#include "sslctx.h"
-#include "sslalloc.h"
-#include "appleCdsa.h"
-#include "sslerrs.h"
-#include "sslutil.h"
-#include "sslDebug.h"
-#include "sslBER.h"
-#include "ModuleAttacher.h"
-
-#ifndef _SSL_KEYCHAIN_H_
-#include "sslKeychain.h"
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include <Security/cssm.h>
-#include <Security/cssmapple.h>
-
-/* X.509 includes, from cssmapi */
-#include <Security/x509defs.h> /* x.509 function and type defs */
-#include <Security/oidsalg.h>
-#include <Security/oidscert.h>
-
-#pragma mark *** Utilities ***
-
-/*
- * Set up a Raw symmetric key with specified algorithm and key bits.
- */
-SSLErr sslSetUpSymmKey(
- CSSM_KEY_PTR symKey,
- CSSM_ALGORITHMS alg,
- CSSM_KEYUSE keyUse, // CSSM_KEYUSE_ENCRYPT, etc.
- CSSM_BOOL copyKey, // true: copy keyData false: set by reference
- uint8 *keyData,
- uint32 keyDataLen) // in bytes
-{
- SSLErr serr;
- CSSM_KEYHEADER *hdr;
-
- memset(symKey, 0, sizeof(CSSM_KEY));
- if(copyKey) {
- serr = stSetUpCssmData(&symKey->KeyData, keyDataLen);
- if(serr) {
- return serr;
- }
- memmove(symKey->KeyData.Data, keyData, keyDataLen);
- }
- else {
- symKey->KeyData.Data = keyData;
- symKey->KeyData.Length = keyDataLen;
- }
-
- /* set up the header */
- hdr = &symKey->KeyHeader;
- hdr->BlobType = CSSM_KEYBLOB_RAW;
- hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
- hdr->AlgorithmId = alg;
- hdr->KeyClass = CSSM_KEYCLASS_SESSION_KEY;
- hdr->LogicalKeySizeInBits = keyDataLen * 8;
- hdr->KeyAttr = CSSM_KEYATTR_MODIFIABLE | CSSM_KEYATTR_EXTRACTABLE;
- hdr->KeyUsage = keyUse;
- hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
- return SSLNoErr;
-}
-
-/*
- * Free a CSSM_KEY - its CSP resources, KCItemRef, and the key itself.
- */
-SSLErr sslFreeKey(
- CSSM_CSP_HANDLE cspHand,
- CSSM_KEY_PTR *key, /* so we can null it out */
- #if ST_KEYCHAIN_ENABLE && ST_KC_KEYS_NEED_REF
- SecKeychainRef *kcItem)
- #else
- void *kcItem)
- #endif
-{
- CASSERT(key != NULL);
-
- if(*key != NULL) {
- if(cspHand != 0) {
- CSSM_FreeKey(cspHand, NULL, *key, CSSM_FALSE);
- }
- sslFree(*key);
- *key = NULL;
- }
- #if ST_KEYCHAIN_ENABLE && ST_KC_KEYS_NEED_REF
- if((kcItem != NULL) && (*kcItem != NULL)) {
- KCReleaseItem(kcItem); /* does this NULL the referent? */
- *kcItem = NULL;
- }
- #endif
- return SSLNoErr;
-}
-
-/*
- * Standard app-level memory functions required by CDSA.
- */
-void * stAppMalloc (uint32 size, void *allocRef) {
- return( malloc(size) );
-}
-void stAppFree (void *mem_ptr, void *allocRef) {
- free(mem_ptr);
- return;
-}
-void * stAppRealloc (void *ptr, uint32 size, void *allocRef) {
- return( realloc( ptr, size ) );
-}
-void * stAppCalloc (uint32 num, uint32 size, void *allocRef) {
- return( calloc( num, size ) );
-}
-
-/*
- * Ensure there's a connection to ctx->cspHand. If there
- * already is one, fine.
- * Note that as of 12/18/00, we assume we're connected to
- * all modules all the time (since we do an attachToAll() in
- * SSLNewContext()).
- */
-SSLErr attachToCsp(SSLContext *ctx)
-{
- CASSERT(ctx != NULL);
- if(ctx->cspHand != 0) {
- return SSLNoErr;
- }
- else {
- return SSLAttachFailure;
- }
-}
-
-/*
- * Connect to TP, CL; reusable.
- */
-SSLErr attachToCl(SSLContext *ctx)
-{
- CASSERT(ctx != NULL);
- if(ctx->clHand != 0) {
- return SSLNoErr;
- }
- else {
- return SSLAttachFailure;
- }
-}
-
-SSLErr attachToTp(SSLContext *ctx)
-{
- CASSERT(ctx != NULL);
- if(ctx->tpHand != 0) {
- return SSLNoErr;
- }
- else {
- return SSLAttachFailure;
- }
-}
-
-/*
- * Convenience function - attach to CSP, CL, TP. Reusable.
- */
-SSLErr attachToAll(SSLContext *ctx)
-{
- CSSM_RETURN crtn;
-
- CASSERT(ctx != NULL);
- crtn = attachToModules(&ctx->cspHand, &ctx->clHand,
- &ctx->tpHand
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- ,
- &ctx->cspDlHand
- #endif
- );
- if(crtn) {
- return SSLAttachFailure;
- }
- else {
- return SSLNoErr;
- }
-}
-
-SSLErr detachFromAll(SSLContext *ctx)
-{
- #if 0
- /* No more, attachments are kept on a global basis */
- CASSERT(ctx != NULL);
- if(ctx->cspHand != 0) {
- CSSM_ModuleDetach(ctx->cspHand);
- ctx->cspHand = 0;
- }
- if(ctx->tpHand != 0) {
- CSSM_ModuleDetach(ctx->tpHand);
- ctx->tpHand = 0;
- }
- if(ctx->clHand != 0) {
- CSSM_ModuleDetach(ctx->clHand);
- ctx->clHand = 0;
- }
- #endif /* 0 */
- return SSLNoErr;
-}
-
-#pragma mark -
-#pragma mark *** CSSM_DATA routines ***
-
-CSSM_DATA_PTR stMallocCssmData(
- uint32 size)
-{
- CSSM_DATA_PTR rtn = (CSSM_DATA_PTR)stAppMalloc(sizeof(CSSM_DATA), NULL);
-
- if(rtn == NULL) {
- return NULL;
- }
- rtn->Length = size;
- if(size == 0) {
- rtn->Data = NULL;
- }
- else {
- rtn->Data = (uint8 *)stAppMalloc(size, NULL);
- }
- return rtn;
-}
-
-void stFreeCssmData(
- CSSM_DATA_PTR data,
- CSSM_BOOL freeStruct)
-{
- if(data == NULL) {
- return;
- }
- if(data->Data != NULL) {
- stAppFree(data->Data, NULL);
- data->Data = NULL;
- }
- data->Length = 0;
- if(freeStruct) {
- stAppFree(data, NULL);
- }
-}
-
-/*
- * Ensure that indicated CSSM_DATA_PTR can handle 'length' bytes of data.
- * Malloc the Data ptr if necessary.
- */
-SSLErr stSetUpCssmData(
- CSSM_DATA_PTR data,
- uint32 length)
-{
- CASSERT(data != NULL);
- if(data->Length == 0) {
- data->Data = (uint8 *)stAppMalloc(length, NULL);
- if(data->Data == NULL) {
- return SSLMemoryErr;
- }
- }
- else if(data->Length < length) {
- errorLog0("stSetUpCssmData: length too small\n");
- return SSLMemoryErr;
- }
- data->Length = length;
- return SSLNoErr;
-}
-
-#pragma mark -
-#pragma mark *** Public CSP Functions ***
-
-/*
- * Common RNG function; replaces SSLRef's SSLRandomFunc.
- * FIXME - just use /dev/random.
- */
-SSLErr sslRand(SSLContext *ctx, SSLBuffer *buf)
-{
- CSSM_RETURN crtn;
- CSSM_CC_HANDLE rngHand;
- CSSM_DATA randData;
- SSLErr serr;
-
- CASSERT(ctx != NULL);
- CASSERT(buf != NULL);
- CASSERT(buf->data != NULL);
-
- serr = attachToCsp(ctx);
- if(serr) {
- return serr;
- }
- if(buf->length == 0) {
- dprintf0("sslRand: zero buf->length\n");
- return SSLNoErr;
- }
-
- /*
- * We happen to know that the CSP has a really good RNG
- * seed if we don't specify anything; let's use it
- */
- crtn = CSSM_CSP_CreateRandomGenContext(ctx->cspHand,
- CSSM_ALGID_APPLE_YARROW,
- NULL, /* seed */
- buf->length,
- &rngHand);
- if(crtn) {
- stPrintCdsaError("CSSM_CSP_CreateRandomGenContext", crtn);
- return SSLCryptoError;
- }
- SSLBUF_TO_CSSM(buf, &randData);
- crtn = CSSM_GenerateRandom(rngHand, &randData);
- if(crtn) {
- stPrintCdsaError("CSSM_GenerateRandom", crtn);
- serr = SSLCryptoError;
- }
- CSSM_DeleteContext(rngHand);
- return serr;
-}
-
-/*
- * Raw RSA sign/verify.
- *
- * Initial X port: CSP doesns't support this, so we'll do sign/verify via
- * raw RSA encrypt/decrypt here.
- */
-#define SIGN_VFY_VIA_ENCR_DECR 0
-
-#if SIGN_VFY_VIA_ENCR_DECR
-
-SSLErr sslRsaRawSign(
- SSLContext *ctx,
- const CSSM_KEY *privKey,
- CSSM_CSP_HANDLE cspHand,
- const UInt8 *plainText,
- UInt32 plainTextLen,
- UInt8 *sig, // mallocd by caller; RETURNED
- UInt32 sigLen, // available
- UInt32 *actualBytes) // RETURNED
-{
- /* Raw RSA sign with no digest is the same as raw RSA encrypt. */
- /* Force CSSM_KEYUSE_ANY in case CL provided keyuse bits more specific
- * than we really want */
- SSLErr serr;
- CSSM_KEYUSE savedKeyUse = privKey->KeyHeader.KeyUsage;
- privKey->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
- serr = sslRsaEncrypt(ctx,
- privKey,
- cspHand,
- plainText,
- plainTextLen,
- sig,
- sigLen,
- actualBytes);
- privKey->KeyHeader.KeyUsage = savedKeyUse;
- return serr;
-}
-
-SSLErr sslRsaRawVerify(
- SSLContext *ctx,
- const CSSM_KEY *pubKey,
- CSSM_CSP_HANDLE cspHand,
- const UInt8 *plainText,
- UInt32 plainTextLen,
- const UInt8 *sig,
- UInt32 sigLen)
-{
- /*
- * Raw RSA verify with no digest is just a comparison of the incoming
- * plaintext with (signature, decrypted via raw RSA decrypt).
- */
-
- UInt32 actualBytes;
- SSLErr serr;
- UInt8 *digest;
-
- /* Force CSSM_KEYUSE_ANY in case CL provided keyuse bits more specific
- * than we really want */
- CSSM_KEYUSE savedKeyUse = pubKey->KeyHeader.KeyUsage;
- pubKey->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
-
- /* malloc space for decrypting the signature */
- digest = sslMalloc(plainTextLen);
- if(digest == NULL) {
- return SSLMemoryErr;
- }
-
- /* decrypt signature */
- serr = sslRsaDecrypt(ctx,
- pubKey,
- cspHand,
- sig,
- sigLen,
- digest,
- plainTextLen,
- &actualBytes);
- pubKey->KeyHeader.KeyUsage = savedKeyUse;
- if(serr) {
- goto errOut;
- }
- if((actualBytes != plainTextLen) ||
- (memcmp(plainText, digest, plainTextLen))) {
- errorLog0("sslRsaRawVerify: sig miscompare\n");
- serr = SSLCryptoError;
- }
- else {
- serr = SSLNoErr;
- }
-errOut:
- sslFree(digest);
- return serr;
-}
-
-#else /* OS9 and future post-cheetah version */
-
-SSLErr sslRsaRawSign(
- SSLContext *ctx,
- const CSSM_KEY *privKey,
- CSSM_CSP_HANDLE cspHand,
- const UInt8 *plainText,
- UInt32 plainTextLen,
- UInt8 *sig, // mallocd by caller; RETURNED
- UInt32 sigLen, // available
- UInt32 *actualBytes) // RETURNED
-{
- CSSM_CC_HANDLE sigHand = 0;
- CSSM_RETURN crtn;
- SSLErr serr;
- CSSM_DATA sigData;
- CSSM_DATA ptextData;
-
- CASSERT(ctx != NULL);
- if((privKey == NULL) ||
- (cspHand == 0) ||
- (plainText == NULL) ||
- (sig == NULL) ||
- (actualBytes == NULL)) {
- errorLog0("sslRsaRawSign: bad arguments\n");
- return SSLInternalError;
- }
- *actualBytes = 0;
-
- crtn = CSSM_CSP_CreateSignatureContext(cspHand,
- CSSM_ALGID_RSA,
- NULL, // passPhrase
- privKey,
- &sigHand);
- if(crtn) {
- stPrintCdsaError("CSSM_CSP_CreateSignatureContext (1)", crtn);
- return SSLCryptoError;
- }
-
- ptextData.Data = (uint8 *)plainText;
- ptextData.Length = plainTextLen;
-
- /* caller better get this right, or the SignData will fail */
- sigData.Data = sig;
- sigData.Length = sigLen;
-
- crtn = CSSM_SignData(sigHand,
- &ptextData,
- 1,
- CSSM_ALGID_NONE, // digestAlg
- &sigData);
- if(crtn) {
- stPrintCdsaError("CSSM_SignData", crtn);
- serr = SSLCryptoError;
- }
- else {
- *actualBytes = sigData.Length;
- serr = SSLNoErr;
- }
- if(sigHand != 0) {
- CSSM_DeleteContext(sigHand);
- }
- return serr;
-}
-
-SSLErr sslRsaRawVerify(
- SSLContext *ctx,
- const CSSM_KEY *pubKey,
- CSSM_CSP_HANDLE cspHand,
- const UInt8 *plainText,
- UInt32 plainTextLen,
- const UInt8 *sig,
- UInt32 sigLen)
-{
- CSSM_CC_HANDLE sigHand = 0;
- CSSM_RETURN crtn;
- SSLErr serr;
- CSSM_DATA sigData;
- CSSM_DATA ptextData;
-
- CASSERT(ctx != NULL);
- if((pubKey == NULL) ||
- (cspHand == 0) ||
- (plainText == NULL) ||
- (sig == NULL)) {
- errorLog0("sslRsaRawVerify: bad arguments\n");
- return SSLInternalError;
- }
-
- crtn = CSSM_CSP_CreateSignatureContext(cspHand,
- CSSM_ALGID_RSA,
- NULL, // passPhrase
- pubKey,
- &sigHand);
- if(sigHand == 0) {
- stPrintCdsaError("CSSM_CSP_CreateSignatureContext (2)", crtn);
- return SSLCryptoError;
- }
-
- ptextData.Data = (uint8 *)plainText;
- ptextData.Length = plainTextLen;
- sigData.Data = (uint8 *)sig;
- sigData.Length = sigLen;
-
- crtn = CSSM_VerifyData(sigHand,
- &ptextData,
- 1,
- CSSM_ALGID_NONE, // digestAlg
- &sigData);
- if(crtn) {
- stPrintCdsaError("CSSM_VerifyData", crtn);
- serr = SSLCryptoError;
- }
- else {
- serr = SSLNoErr;
- }
- if(sigHand != 0) {
- CSSM_DeleteContext(sigHand);
- }
- return serr;
-}
-#endif /* SIGN_VFY_VIA_ENCR_DECR */
-
-/*
- * Encrypt/Decrypt
- */
-#if APPLE_DOMESTIC_CSP_REQUIRED
-
-/*
- * Mucho work needed to get this functionality out of export CSP....
- */
-
-SSLErr sslRsaEncrypt(
- SSLContext *ctx,
- const CSSM_KEY *pubKey,
- CSSM_CSP_HANDLE cspHand,
- const UInt8 *plainText,
- UInt32 plainTextLen,
- UInt8 *cipherText, // mallocd by caller; RETURNED
- UInt32 cipherTextLen, // available
- UInt32 *actualBytes) // RETURNED
-{
- CSSM_DATA ctextData = {0, NULL};
- CSSM_DATA ptextData;
- CSSM_DATA remData = {0, NULL};
- CSSM_CC_HANDLE cryptHand = 0;
- SSLErr serr = SSLInternalError;
- CSSM_RETURN crtn;
- uint32 bytesMoved = 0;
- CSSM_ACCESS_CREDENTIALS creds;
-
- CASSERT(ctx != NULL);
- CASSERT(actualBytes != NULL);
- *actualBytes = 0;
-
- if((pubKey == NULL) || (cspHand == 0)) {
- errorLog0("sslRsaEncrypt: bad pubKey/cspHand\n");
- return SSLInternalError;
- }
-
- #if RSA_PUB_KEY_USAGE_HACK
- ((CSSM_KEY_PTR)pubKey)->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT;
- #endif
- memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
-
- crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
- CSSM_ALGID_RSA,
- &creds,
- pubKey,
- CSSM_PADDING_PKCS1,
- &cryptHand);
- if(crtn) {
- stPrintCdsaError("CSSM_CSP_CreateAsymmetricContext", crtn);
- return SSLCryptoError;
- }
- ptextData.Data = (uint8 *)plainText;
- ptextData.Length = plainTextLen;
-
- if(pubKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY) {
- /*
- * Special case, encrypting with private key (i.e., raw sign). Add
- * the required context attr.
- */
- CSSM_CONTEXT_ATTRIBUTE modeAttr;
-
- modeAttr.AttributeType = CSSM_ATTRIBUTE_MODE;
- modeAttr.AttributeLength = sizeof(uint32);
- modeAttr.Attribute.Uint32 = CSSM_ALGMODE_PRIVATE_KEY;
- crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &modeAttr);
- if(crtn) {
- stPrintCdsaError("CSSM_UpdateContextAttributes", crtn);
- CSSM_DeleteContext(cryptHand);
- return SSLCryptoError;
- }
- }
-
- /*
- * Have CSP malloc ciphertext
- */
- crtn = CSSM_EncryptData(cryptHand,
- &ptextData,
- 1,
- &ctextData,
- 1,
- &bytesMoved,
- &remData);
- if(crtn == CSSM_OK) {
- /*
- * ciphertext in both ctextData and remData; ensure it'll fit
- * in caller's buf & copy
- */
- if(bytesMoved > cipherTextLen) {
- errorLog2("sslRsaEncrypt overflow; cipherTextLen %ld bytesMoved %ld\n",
- cipherTextLen, bytesMoved);
- serr = SSLDataOverflow;
- }
- else {
- UInt32 toMoveCtext;
- UInt32 toMoveRem;
-
- *actualBytes = bytesMoved;
- /*
- * Snag valid data from ctextData - its length or bytesMoved,
- * whichever is less
- */
- if(ctextData.Length > bytesMoved) {
- /* everything's in ctext */
- toMoveCtext = bytesMoved;
- toMoveRem = 0;
- }
- else {
- /* must be some in remData too */
- toMoveCtext = ctextData.Length;
- toMoveRem = bytesMoved - toMoveCtext; // remainder
- }
- if(toMoveCtext) {
- memmove(cipherText, ctextData.Data, toMoveCtext);
- }
- if(toMoveRem) {
- memmove(cipherText + toMoveCtext, remData.Data,
- toMoveRem);
- }
- serr = SSLNoErr;
- }
- }
- else {
- stPrintCdsaError("CSSM_EncryptData", crtn);
- serr = SSLCryptoError;
- }
- if(cryptHand != 0) {
- CSSM_DeleteContext(cryptHand);
- }
-
- /* free data mallocd by CSP */
- stFreeCssmData(&ctextData, CSSM_FALSE);
- stFreeCssmData(&remData, CSSM_FALSE);
- return serr;
-}
-
-SSLErr sslRsaDecrypt(
- SSLContext *ctx,
- const CSSM_KEY *privKey,
- CSSM_CSP_HANDLE cspHand,
- const UInt8 *cipherText,
- UInt32 cipherTextLen,
- UInt8 *plainText, // mallocd by caller; RETURNED
- UInt32 plainTextLen, // available
- UInt32 *actualBytes) // RETURNED
-{
- CSSM_DATA ptextData = {0, NULL};
- CSSM_DATA ctextData;
- CSSM_DATA remData = {0, NULL};
- CSSM_CC_HANDLE cryptHand = 0;
- SSLErr serr = SSLInternalError;
- CSSM_RETURN crtn;
- uint32 bytesMoved = 0;
- CSSM_ACCESS_CREDENTIALS creds;
-
- CASSERT(ctx != NULL);
- CASSERT(actualBytes != NULL);
- *actualBytes = 0;
-
- if((privKey == NULL) || (cspHand == 0)) {
- errorLog0("sslRsaDecrypt: bad privKey/cspHand\n");
- return SSLInternalError;
- }
- memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
- crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
- CSSM_ALGID_RSA,
- &creds,
- privKey,
- CSSM_PADDING_PKCS1,
- &cryptHand);
- if(crtn) {
- stPrintCdsaError("CSSM_CSP_CreateAsymmetricContext", crtn);
- return SSLCryptoError;
- }
- ctextData.Data = (uint8 *)cipherText;
- ctextData.Length = cipherTextLen;
-
- if(privKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PUBLIC_KEY) {
- /*
- * Special case, decrypting with public key (i.e., raw verify). Add
- * the required context attr.
- */
- CSSM_CONTEXT_ATTRIBUTE modeAttr;
-
- modeAttr.AttributeType = CSSM_ATTRIBUTE_MODE;
- modeAttr.AttributeLength = sizeof(uint32);
- modeAttr.Attribute.Uint32 = CSSM_ALGMODE_PUBLIC_KEY;
- crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &modeAttr);
- if(crtn) {
- stPrintCdsaError("CSSM_UpdateContextAttributes", crtn);
- CSSM_DeleteContext(cryptHand);
- return SSLCryptoError;
- }
- }
-
- /*
- * Have CSP malloc plaintext
- */
- crtn = CSSM_DecryptData(cryptHand,
- &ctextData,
- 1,
- &ptextData,
- 1,
- &bytesMoved,
- &remData);
- if(crtn == CSSM_OK) {
- /*
- * plaintext in both ptextData and remData; ensure it'll fit
- * in caller's buf & copy
- */
- if(bytesMoved > plainTextLen) {
- errorLog2("sslRsaDecrypt overflow; plainTextLen %ld bytesMoved %ld\n",
- plainTextLen, bytesMoved);
- serr = SSLDataOverflow;
- }
- else {
- UInt32 toMovePtext;
- UInt32 toMoveRem;
-
- *actualBytes = bytesMoved;
- /*
- * Snag valid data from ptextData - its length or bytesMoved,
- * whichever is less
- */
- if(ptextData.Length > bytesMoved) {
- /* everything's in ptext */
- toMovePtext = bytesMoved;
- toMoveRem = 0;
- }
- else {
- /* must be some in remData too */
- toMovePtext = ptextData.Length;
- toMoveRem = bytesMoved - toMovePtext; // remainder
- }
- if(toMovePtext) {
- memmove(plainText, ptextData.Data, toMovePtext);
- }
- if(toMoveRem) {
- memmove(plainText + toMovePtext, remData.Data,
- toMoveRem);
- }
- serr = SSLNoErr;
- }
- }
- else {
- stPrintCdsaError("CSSM_DecryptData", crtn);
- serr = SSLCryptoError;
- }
- if(cryptHand != 0) {
- CSSM_DeleteContext(cryptHand);
- }
-
- /* free data mallocd by CSP */
- stFreeCssmData(&ptextData, CSSM_FALSE);
- stFreeCssmData(&remData, CSSM_FALSE);
- return serr;
-}
-
-#endif /* APPLE_DOMESTIC_CSP_REQUIRED */
-
-/*
- * Obtain size of key in bytes.
- */
-UInt32 sslKeyLengthInBytes(const CSSM_KEY *key)
-{
- CASSERT(key != NULL);
- return (((key->KeyHeader.LogicalKeySizeInBits) + 7) / 8);
-}
-
-/*
- * Get raw key bits from an RSA public key.
- */
-SSLErr sslGetPubKeyBits(
- SSLContext *ctx,
- const CSSM_KEY *pubKey,
- CSSM_CSP_HANDLE cspHand,
- SSLBuffer *modulus, // data mallocd and RETURNED
- SSLBuffer *exponent) // data mallocd and RETURNED
-{
- CSSM_KEY wrappedKey;
- CSSM_BOOL didWrap = CSSM_FALSE;
- const CSSM_KEYHEADER *hdr;
- CSSM_CC_HANDLE ccHand;
- CSSM_RETURN crtn;
- SSLBuffer pubKeyBlob;
- SSLErr srtn;
- CSSM_ACCESS_CREDENTIALS creds;
-
- CASSERT(ctx != NULL);
- CASSERT(modulus != NULL);
- CASSERT(exponent != NULL);
- CASSERT(pubKey != NULL);
-
- hdr = &pubKey->KeyHeader;
- if(hdr->KeyClass != CSSM_KEYCLASS_PUBLIC_KEY) {
- errorLog1("sslGetPubKeyBits: bad keyClass (%ld)\n", hdr->KeyClass);
- return SSLInternalError;
- }
- if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
- errorLog1("sslGetPubKeyBits: bad AlgorithmId (%ld)\n", hdr->AlgorithmId);
- return SSLInternalError;
- }
-
- /*
- * Handle possible reference format - I think it should be in
- * blob form since it came from the DL, but conversion is
- * simple.
- */
- switch(hdr->BlobType) {
- case CSSM_KEYBLOB_RAW:
- /* easy case */
- CSSM_TO_SSLBUF(&pubKey->KeyData, &pubKeyBlob);
- break;
-
- case CSSM_KEYBLOB_REFERENCE:
- /*
- * Convert to a blob via "NULL wrap"; no wrapping key,
- * ALGID_NONE
- */
- srtn = attachToCsp(ctx);
- if(srtn) {
- return srtn;
- }
- memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
- crtn = CSSM_CSP_CreateSymmetricContext(ctx->cspHand,
- CSSM_ALGID_NONE,
- CSSM_ALGMODE_NONE,
- &creds, // creds
- pubKey,
- NULL, // InitVector
- CSSM_PADDING_NONE,
- 0, // reserved
- &ccHand);
- if(crtn) {
- stPrintCdsaError("sslGetPubKeyBits: CreateSymmetricContext failure", crtn);
- return SSLMemoryErr;
- }
- memset(&wrappedKey, 0, sizeof(CSSM_KEY));
- crtn = CSSM_WrapKey(ccHand,
- &creds,
- pubKey,
- NULL, // descriptiveData
- &wrappedKey);
- CSSM_DeleteContext(ccHand);
- if(crtn) {
- stPrintCdsaError("CSSM_WrapKey", crtn);
- return SSLCryptoError;
- }
- hdr = &wrappedKey.KeyHeader;
- if(hdr->BlobType != CSSM_KEYBLOB_RAW) {
- errorLog1("sslGetPubKeyBits: bad BlobType (%ld) after WrapKey\n",
- hdr->BlobType);
- return SSLCryptoError;
- }
- didWrap = CSSM_TRUE;
- CSSM_TO_SSLBUF(&wrappedKey.KeyData, &pubKeyBlob);
- break;
-
- default:
- errorLog1("sslGetPubKeyBits: bad BlobType (%ld)\n",
- hdr->BlobType);
- return SSLInternalError;
-
- } /* switch BlobType */
-
- CASSERT(hdr->BlobType == CSSM_KEYBLOB_RAW);
- srtn = sslDecodeRsaBlob(&pubKeyBlob, modulus, exponent);
- if(didWrap) {
- CSSM_FreeKey(ctx->cspHand, NULL, &wrappedKey, CSSM_FALSE);
- }
- return srtn;
-}
-
-/*
- * Given raw RSA key bits, cook up a CSSM_KEY_PTR. Used in
- * Server-initiated key exchange.
- */
-SSLErr sslGetPubKeyFromBits(
- SSLContext *ctx,
- const SSLBuffer *modulus,
- const SSLBuffer *exponent,
- CSSM_KEY_PTR *pubKey, // mallocd and RETURNED
- CSSM_CSP_HANDLE *cspHand) // RETURNED
-{
- CSSM_KEY_PTR key = NULL;
- SSLErr serr;
- SSLBuffer blob;
- CSSM_KEYHEADER_PTR hdr;
- CSSM_KEY_SIZE keySize;
- CSSM_RETURN crtn;
-
- CASSERT((ctx != NULL) && (modulus != NULL) && (exponent != NULL));
- CASSERT((pubKey != NULL) && (cspHand != NULL));
-
- *pubKey = NULL;
- *cspHand = 0;
-
- serr = attachToCsp(ctx);
- if(serr) {
- return serr;
- }
- serr = sslEncodeRsaBlob(modulus, exponent, &blob);
- if(serr) {
- return serr;
- }
-
- /* the rest is boilerplate, cook up a good-looking public key */
- key = sslMalloc(sizeof(CSSM_KEY));
- if(key == NULL) {
- return SSLMemoryErr;
- }
- memset(key, 0, sizeof(CSSM_KEY));
- hdr = &key->KeyHeader;
-
- hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
- /* key_ptr->KeyHeader.CspId is unknown (remains 0) */
- hdr->BlobType = CSSM_KEYBLOB_RAW;
- hdr->AlgorithmId = CSSM_ALGID_RSA;
- hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
- hdr->KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
- /* comply with ASA requirements */
- hdr->KeyUsage = CSSM_KEYUSE_VERIFY;
- hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
- /* key_ptr->KeyHeader.StartDate is unknown (remains 0) */
- /* key_ptr->KeyHeader.EndDate is unknown (remains 0) */
- hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
- hdr->WrapMode = CSSM_ALGMODE_NONE;
-
- /* blob->data was mallocd by sslEncodeRsaBlob, pass it over to
- * actual key */
- SSLBUF_TO_CSSM(&blob, &key->KeyData);
-
- /*
- * Get keySizeInBits. This also serves to validate the key blob
- * we just cooked up.
- */
- crtn = CSSM_QueryKeySizeInBits(ctx->cspHand, CSSM_INVALID_HANDLE, key, &keySize);
- if(crtn) {
- stPrintCdsaError("sslGetPubKeyFromBits: QueryKeySizeInBits\n", crtn);
- serr = SSLCryptoError;
- goto abort;
- }
-
- /* success */
- hdr->LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits;
- *pubKey = key;
- *cspHand = ctx->cspHand;
- return SSLNoErr;
-
-abort:
- /* note this frees the blob */
- sslFreeKey(ctx->cspHand, &key, NULL);
- return serr;
-}
-
-#pragma mark -
-#pragma mark *** Public Certificate Functions ***
-
-/*
- * Given a DER-encoded cert, obtain its public key as a CSSM_KEY_PTR.
- * Caller must CSSM_FreeKey and free the CSSM_KEY_PTR itself.
- *
- * For now, the returned cspHand is a copy of ctx->cspHand, so it
- * doesn't have to be detached later - this may change.
- *
- * Update: since CSSM_CL_CertGetKeyInfo() doesn't provide a means for
- * us to tell the CL what CSP to use, we really have no way of knowing
- * what is going on here...we return the process-wide (bare) cspHand,
- * which is currently always able to deal with this raw public key.
- */
-SSLErr sslPubKeyFromCert(
- SSLContext *ctx,
- const SSLBuffer *derCert,
- CSSM_KEY_PTR *pubKey, // RETURNED
- CSSM_CSP_HANDLE *cspHand) // RETURNED
-{
- SSLErr serr;
- CSSM_DATA certData;
- CSSM_RETURN crtn;
-
- CASSERT(ctx != NULL);
- CASSERT(derCert != NULL);
- CASSERT(pubKey != NULL);
- CASSERT(cspHand != NULL);
-
- *pubKey = NULL;
- *cspHand = 0;
-
- serr = attachToCl(ctx);
- if(serr) {
- return serr;
- }
- serr = attachToCsp(ctx);
- if(serr) {
- return serr;
- }
- SSLBUF_TO_CSSM(derCert, &certData);
- crtn = CSSM_CL_CertGetKeyInfo(ctx->clHand, &certData, pubKey);
- if(crtn) {
- return SSLBadCert;
- }
- else {
- *cspHand = ctx->cspHand;
- return SSLNoErr;
- }
-}
-
-#if 0
-
-#include <Files.h>
-#include <Errors.h>
-
-/* for writing root cert to a file */
-
-static OSErr writeBlob(const CSSM_DATA_PTR blob,
- const char *fileName)
-{
- OSErr err = noErr;
- FSSpec fsp;
- short fileRef;
- long count = blob->Length;
- int len = strlen(fileName);
-
- fsp.vRefNum = 0;
- fsp.parID = 0;
- fsp.name[0] = len;
- memmove(&fsp.name[1], fileName, len);
-
- err = FSpCreate(&fsp, 0, 0, 0);
- if(err && (err != dupFNErr)) {
- dprintf1("***FSpCreate() returned %d\n", err);
- return err;
- }
- err = FSpOpenDF(&fsp, fsRdWrPerm, &fileRef);
- if(err) {
- dprintf1("***FSpOpenDF() returned %d\n", err);
- return err;
- }
- err = FSWrite(fileRef, &count, blob->Data);
- if(err) {
- dprintf1("***FSWrite() returned %d\n", err);
- return err;
- }
- err = FSClose(fileRef);
- if(err) {
- dprintf1("***FSClose() returned %d\n", err);
- return err;
- }
- return 0;
-}
-
-void writeBufBlob(const SSLBuffer *blob,
- const char *fileName)
-{
- CSSM_DATA d;
-
- SSLBUF_TO_CSSM(blob, &d)
- writeBlob(&d, fileName);
-}
-
-#endif /* 0 */
-
-#if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
-
-/*
- * Given a CSSM_CERTGROUP which fails due to CSSM_TP_INVALID_ANCHOR
- * (chain verifies to an unknown root):
- *
- * -- find the root cert
- * -- add it to newRootCertKc if present (else error)
- * -- add it to trustedCerts
- * -- re-verify certgroup, demand full success
- */
-static SSLErr sslHandleNewRoot(
- SSLContext *ctx,
- CSSM_CERTGROUP_PTR certGroup)
-{
- int i;
- CSSM_DATA_PTR rootCert;
- CSSM_BOOL expired;
- SSLErr serr;
- CSSM_BOOL brtn;
-
- CASSERT(ctx != NULL);
- CASSERT(certGroup != NULL);
-
- if(ctx->newRootCertKc == NULL) {
- /* no place to add this; done */
- return SSLUnknownRootCert;
- }
-
- /*
- * The root cert "should" be at the end of the chain, but
- * let's not assume that. (We are assuming that there is
- * only one root in the cert group...)
- */
- for(i=0; i<certGroup->NumCerts; i++) {
- rootCert = &certGroup->CertList[i];
- if(sslVerifyCert(ctx, rootCert, rootCert, ctx->cspHand, &expired)) {
- break;
- }
- }
- if(i == certGroup->NumCerts) {
- /* Huh! no root cert!? We should not have been called! */
- errorLog0("sslHandleNewRoot: no root cert!\n");
- return SSLInternalError;
- }
-
- /*
- * Add to newRootCertKc. This may well fail due to user interaction.
- */
- serr = sslAddNewRoot(ctx, rootCert);
- if(serr) {
- return serr;
- }
-
- /*
- * Just to be sure...reverify the whole cert chain.
- */
- brtn = CSSM_TP_CertGroupVerify(
- ctx->tpHand,
- ctx->clHand,
- ctx->cspHand,
- NULL, // DBList
- NULL, // PolicyIdentifiers
- 0, // NumberofPolicyIdentifiers
- CSSM_TP_STOP_ON_POLICY,
- certGroup,
- ctx->trustedCerts, // AnchorCerts
- ctx->numTrustedCerts,
- NULL, // VerifyScope
- 0, // ScopeSize
- 0, // Action
- 0, // Data
- NULL, // evidence
- NULL); // evidenceSize
- if(brtn == CSSM_FALSE) {
- errorLog0("sslHandleNewRoot: adding new root did not help!\n");
- return SSLUnknownRootCert;
- }
- return SSLNoErr;
-}
-
-#endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
-
-/* free a CSSM_CERT_GROUP */
-static void sslFreeCertGroup(
- CSSM_CERTGROUP_PTR certGroup,
- CSSM_BOOL freeCerts, // free individual cert fields
- CSSM_BOOL freeStruct) // free the overall CSSM_CERTGROUP
-{
- unsigned dex;
-
- if(certGroup == NULL) {
- return;
- }
-
- /* free the individual cert Data fields */
- if(certGroup->GroupList.CertList) {
- if(freeCerts) {
- for(dex=0; dex<certGroup->NumCerts; dex++) {
- stFreeCssmData(&certGroup->GroupList.CertList[dex], CSSM_FALSE);
- }
- }
- /* and the array of CSSM_DATAs */
- stAppFree(certGroup->GroupList.CertList, NULL);
- }
- if(freeStruct) {
- stAppFree(certGroup, NULL);
- }
-}
-
-/*
- * Verify a chain of DER-encoded certs.
- * First cert in a chain is root; this must also be present
- * in ctx->trustedCerts.
- */
-SSLErr sslVerifyCertChain(
- SSLContext *ctx,
- const SSLCertificate *certChain)
-{
- UInt32 numCerts;
- CSSM_CERTGROUP certGroup;
- int i;
- SSLErr serr;
- SSLCertificate *c = (SSLCertificate *)certChain;
- CSSM_RETURN crtn;
- CSSM_TP_VERIFY_CONTEXT vfyCtx;
- CSSM_TP_CALLERAUTH_CONTEXT authCtx;
- CSSM_FIELD policyId;
- CSSM_DL_DB_LIST dbList;
- CSSM_APPLE_TP_SSL_OPTIONS sslOpts;
- CSSM_APPLE_TP_ACTION_DATA actionData;
-
- /* FIXME - allowAnyRoot should probably mean "return success" with
- * no checking */
-
- numCerts = SSLGetCertificateChainLength(certChain);
- if(numCerts == 0) {
- /* nope */
- return SSLBadCert;
- }
- #if 0
- serr = attachToAll(ctx);
- if(serr) {
- return serr;
- }
- #endif
-
- /*
- * SSLCertificate chain --> CSSM TP cert group.
- * TP Cert group has root at the end, opposite of
- * SSLCertificate chain.
- */
- certGroup.GroupList.CertList =
- (CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA));
- if(certGroup.GroupList.CertList == NULL) {
- return SSLMemoryErr;
- }
- certGroup.CertGroupType = CSSM_CERTGROUP_DATA;
- certGroup.CertType = CSSM_CERT_X_509v3;
- certGroup.CertEncoding = CSSM_CERT_ENCODING_DER;
- certGroup.NumCerts = numCerts;
-
- memset(certGroup.GroupList.CertList, 0, numCerts * sizeof(CSSM_DATA));
-
- for(i=numCerts-1; i>=0; i--) {
- SSLBUF_TO_CSSM(&c->derCert, &certGroup.GroupList.CertList[i]);
- c = c->next;
- }
-
- memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT));
- vfyCtx.Action = CSSM_TP_ACTION_DEFAULT;
- vfyCtx.Cred = &authCtx;
-
- /* CSSM_TP_CALLERAUTH_CONTEXT components */
- /*
- typedef struct cssm_tp_callerauth_context {
- CSSM_TP_POLICYINFO Policy;
- CSSM_TIMESTRING VerifyTime;
- CSSM_TP_STOP_ON VerificationAbortOn;
- CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert;
- uint32 NumberOfAnchorCerts;
- CSSM_DATA_PTR AnchorCerts;
- CSSM_DL_DB_LIST_PTR DBList;
- CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials;
- } CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR;
- */
-
- /* SSL-specific FieldValue */
- sslOpts.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
- sslOpts.ServerNameLen = ctx->peerDomainNameLen;
- sslOpts.ServerName = ctx->peerDomainName;
-
- /* TP-wide ActionData */
- actionData.Version = CSSM_APPLE_TP_ACTION_VERSION;
- actionData.ActionFlags = 0x80000000; // @@@ secret root-cert-enable
- if(ctx->allowExpiredCerts) {
- actionData.ActionFlags |= CSSM_TP_ACTION_ALLOW_EXPIRED;
- }
- vfyCtx.ActionData.Data = (uint8 *)&actionData;
- vfyCtx.ActionData.Length = sizeof(actionData);
-
- /* zero or one policy here */
- policyId.FieldOid = CSSMOID_APPLE_TP_SSL;
- policyId.FieldValue.Data = (uint8 *)&sslOpts;
- policyId.FieldValue.Length = sizeof(sslOpts);
- authCtx.Policy.NumberOfPolicyIds = 1;
- authCtx.Policy.PolicyIds = &policyId;
-
- authCtx.VerifyTime = NULL;
- authCtx.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY;
- authCtx.CallbackWithVerifiedCert = NULL;
- authCtx.NumberOfAnchorCerts = ctx->numTrustedCerts;
- authCtx.AnchorCerts = ctx->trustedCerts;
- memset(&dbList, 0, sizeof(CSSM_DL_DB_LIST));
- authCtx.DBList = &dbList;
- authCtx.CallerCredentials = NULL;
-
- /*
- * Here we go; hand it over to TP. Note trustedCerts are our
- * known good Anchor certs; they're already formatted properly.
- * Unlike most other Apple code, we demand full success here,
- * implying that the last cert in the chain is indeed an Anchor
- * cert. We already know that all of our anchor certs are
- * roots, so on successful return, we'll know the incoming
- * chain has a root, it verifies to that root, and that that
- * root is in trustedCerts.
- */
- crtn = CSSM_TP_CertGroupVerify(ctx->tpHand,
- ctx->clHand,
- ctx->cspHand,
- &certGroup,
- &vfyCtx,
- NULL); // no evidence needed
-
- serr = SSLNoErr;
- if(crtn) {
- /* get some detailed error info */
- switch(crtn) {
- case CSSMERR_TP_INVALID_ANCHOR_CERT:
- /* root found but we don't trust it */
- if(ctx->allowAnyRoot) {
- dprintf0("***Warning: accepting unknown root cert\n");
- break;
- }
- #if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
- if(ctx->newRootCertKc != NULL) {
- /* see if user wants to handle new root */
- serr = sslHandleNewRoot(ctx, &certGroup);
- }
- else {
- serr = SSLUnknownRootCert;
- }
- #else
- serr = SSLUnknownRootCert;
- #endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
- break;
- case CSSMERR_TP_NOT_TRUSTED:
- /* no root, not even in implicit SSL roots */
- if(ctx->allowAnyRoot) {
- dprintf0("***Warning: accepting unverified cert chain\n");
- break;
- }
- serr = SSLNoRootCert;
- break;
- case CSSMERR_TP_CERT_EXPIRED:
- assert(!ctx->allowExpiredCerts);
- serr = SSLCertExpired;
- break;
- case CSSMERR_TP_CERT_NOT_VALID_YET:
- serr = SSLCertNotYetValid;
- break;
- default:
- stPrintCdsaError(
- "sslVerifyCertChain: CSSM_TP_CertGroupVerify returned", crtn);
- serr = X509CertChainInvalidErr;
- break;
- }
- } /* brtn FALSE */
-
- /*
- * don't free individual certs - caller still owns them
- * don't free struct - on stack
- */
- sslFreeCertGroup(&certGroup, CSSM_FALSE, CSSM_FALSE);
- return serr;
-}
-
-
-#if 0
-/* not needed in X */
-
-/*
- * Given two certs, verify subjectCert with issuerCert. Returns
- * CSSM_TRUE on successful verify.
- * Only special case on error is "subject cert expired", indicated by
- * *subjectExpired returned as CSSM_TRUE.
- */
-CSSM_BOOL sslVerifyCert(
- SSLContext *ctx,
- const CSSM_DATA_PTR subjectCert,
- const CSSM_DATA_PTR issuerCert,
- CSSM_CSP_HANDLE cspHand, // can verify with issuerCert
- CSSM_BOOL *subjectExpired) // RETURNED
-{
- CSSM_KEY_PTR issuerPubKey = NULL;
- CSSM_DATA_PTR sigOid = NULL;
- CSSM_HANDLE ResultsHandle;
- uint32 NumberOfFields;
- CSSM_ERROR_PTR pErr = NULL;
- CSSM_BOOL brtn;
- uint32 *algId = NULL; // mallocd by CL_Passthrough
- CSSM_CC_HANDLE ccHand = 0;
-
- *subjectExpired = CSSM_FALSE;
-
- /* ensure connection to CL, TP */
- if(attachToCl(ctx)) {
- return CSSM_FALSE;
- }
- if(attachToTp(ctx)) {
- return CSSM_FALSE;
- }
-
- /* public key from issuer cert */
- issuerPubKey = CSSM_CL_CertGetKeyInfo(ctx->clHand, issuerCert);
- if(issuerPubKey == NULL) {
- return CSSM_FALSE;
- }
- /* subsequent errors to abort: */
-
- /* signature alg from subject cert */
- sigOid = CSSM_CL_CertGetFirstFieldValue(ctx->clHand,
- subjectCert,
- &CSSMOID_X509V1SignatureAlgorithm,
- &ResultsHandle,
- &NumberOfFields);
- if(sigOid == NULL) {
- stPrintCdsaError("CSSM_CL_CertGetFirstFieldValue");
- brtn = CSSM_FALSE;
- CSSM_CL_CertAbortQuery(ctx->clHand, ResultsHandle);
- goto abort;
- }
- /* cleanup query state */
- CSSM_CL_CertAbortQuery(ctx->clHand, ResultsHandle);
-
- /* convert: alg OID to CSSM_ALGID_xxx */
- algId = (uint32 *)CSSM_CL_PassThrough(ctx->clHand,
- 0, // no handle needed
- INTEL_X509V3_PASSTHROUGH_ALGOID_TO_ALGID,
- sigOid);
- if(*algId == CSSM_ALGID_NONE) {
- brtn = CSSM_FALSE;
- goto abort;
- }
-
- /* set up a sign context with obtained pub key and algorithm */
- ccHand = CSSM_CSP_CreateSignatureContext(cspHand,
- *algId,
- NULL, // no passphrase
- issuerPubKey);
- if(ccHand == 0) {
- brtn = CSSM_FALSE;
- goto abort;
- }
-
- /* go for it - CL takes over from here */
- brtn = CSSM_CL_CertVerify(ctx->clHand,
- ccHand,
- subjectCert,
- issuerCert,
- NULL, // VerifyScope
- 0); // ScopeSize
- if(!brtn && (CSSM_GetError()->error == CSSM_CL_CERT_EXPIRED)) {
- *subjectExpired = CSSM_TRUE;
- }
-
-abort:
- if(issuerPubKey != NULL) {
- CSSM_Free(issuerPubKey->KeyData.Data);
- CSSM_Free(issuerPubKey);
- }
- if(sigOid != NULL) {
- CSSM_Free(sigOid->Data);
- CSSM_Free(sigOid);
- }
- if(ccHand != 0) {
- CSSM_DeleteContext(ccHand);
- }
- if(algId != NULL) {
- CSSM_Free(algId);
- }
- return brtn;
-}
-#endif /* 0 - not needed */
-
-#if ST_KEYCHAIN_ENABLE
-/* no cert parsing in this version */
-
-/*
- * Given a DER-encoded cert, obtain its DER-encoded subject name.
- */
-CSSM_DATA_PTR sslGetCertSubjectName(
- SSLContext *ctx,
- const CSSM_DATA_PTR cert)
-{
- uint32 NumberOfFields = 0;
- CSSM_HANDLE ResultsHandle = 0;
- CSSM_DATA_PTR pEncodedName = NULL;
- CSSM_RETURN crtn;
-
- /* ensure connection to CL */
- if(attachToCl(ctx)) {
- return NULL;
- }
- crtn = CSSM_CL_CertGetFirstFieldValue(
- ctx->clHand,
- cert,
- &CSSMOID_X509V1SubjectName,
- &ResultsHandle,
- &NumberOfFields,
- &pEncodedName);
- if(crtn) {
- stPrintCdsaError("CertGetFirstFieldValue", crtn);
- }
- CSSM_CL_CertAbortQuery(ctx->clHand, ResultsHandle);
- return pEncodedName;
-}
-#endif ST_KEYCHAIN_ENABLE
-
-#if (SSL_DEBUG && ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS)
-void verifyTrustedRoots(SSLContext *ctx,
- CSSM_DATA_PTR certs,
- unsigned numCerts)
-{
- int i;
- CSSM_DATA_PTR cert;
- CSSM_BOOL expired;
-
- for(i=0; i<numCerts; i++) {
- cert = &certs[i];
- if(!sslVerifyCert(ctx,
- cert,
- cert,
- ctx->cspHand,
- &expired)) {
- sslPanic("Bad trusted cert!\n");
- }
- }
-}
-#endif
-
-
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: appleCdsa.cpp
+
+ Contains: interface between SSL and CDSA
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "sslContext.h"
+#include "sslMemory.h"
+#include "appleCdsa.h"
+#include "sslUtils.h"
+#include "sslDebug.h"
+#include "sslBER.h"
+#include "ModuleAttacher.h"
+
+#ifndef _SSL_KEYCHAIN_H_
+#include "sslKeychain.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <Security/cssm.h>
+#include <Security/cssmapple.h>
+#include <Security/cssmerrno.h>
+
+/* X.509 includes, from cssmapi */
+#include <Security/x509defs.h> /* x.509 function and type defs */
+#include <Security/oidsalg.h>
+#include <Security/oidscert.h>
+
+#pragma mark *** Utilities ***
+
+/*
+ * Set up a Raw symmetric key with specified algorithm and key bits.
+ */
+OSStatus sslSetUpSymmKey(
+ CSSM_KEY_PTR symKey,
+ CSSM_ALGORITHMS alg,
+ CSSM_KEYUSE keyUse, // CSSM_KEYUSE_ENCRYPT, etc.
+ CSSM_BOOL copyKey, // true: copy keyData false: set by reference
+ uint8 *keyData,
+ uint32 keyDataLen) // in bytes
+{
+ OSStatus serr;
+ CSSM_KEYHEADER *hdr;
+
+ memset(symKey, 0, sizeof(CSSM_KEY));
+ if(copyKey) {
+ serr = stSetUpCssmData(&symKey->KeyData, keyDataLen);
+ if(serr) {
+ return serr;
+ }
+ memmove(symKey->KeyData.Data, keyData, keyDataLen);
+ }
+ else {
+ symKey->KeyData.Data = keyData;
+ symKey->KeyData.Length = keyDataLen;
+ }
+
+ /* set up the header */
+ hdr = &symKey->KeyHeader;
+ hdr->BlobType = CSSM_KEYBLOB_RAW;
+ hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+ hdr->AlgorithmId = alg;
+ hdr->KeyClass = CSSM_KEYCLASS_SESSION_KEY;
+ hdr->LogicalKeySizeInBits = keyDataLen * 8;
+ hdr->KeyAttr = CSSM_KEYATTR_MODIFIABLE | CSSM_KEYATTR_EXTRACTABLE;
+ hdr->KeyUsage = keyUse;
+ hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
+ return noErr;
+}
+
+/*
+ * Free a CSSM_KEY - its CSP resources, KCItemRef, and the key itself.
+ */
+OSStatus sslFreeKey(
+ CSSM_CSP_HANDLE cspHand,
+ CSSM_KEY_PTR *key, /* so we can null it out */
+ #if ST_KC_KEYS_NEED_REF
+ SecKeychainRef *kcItem)
+ #else
+ void *kcItem)
+ #endif
+{
+ assert(key != NULL);
+
+ if(*key != NULL) {
+ if(cspHand != 0) {
+ CSSM_FreeKey(cspHand, NULL, *key, CSSM_FALSE);
+ }
+ stAppFree(*key, NULL); // key mallocd by CL using our callback
+ *key = NULL;
+ }
+ #if ST_KC_KEYS_NEED_REF
+ if((kcItem != NULL) && (*kcItem != NULL)) {
+ KCReleaseItem(kcItem); /* does this NULL the referent? */
+ *kcItem = NULL;
+ }
+ #endif
+ return noErr;
+}
+
+/*
+ * Standard app-level memory functions required by CDSA.
+ */
+void * stAppMalloc (uint32 size, void *allocRef) {
+ return( malloc(size) );
+}
+void stAppFree (void *mem_ptr, void *allocRef) {
+ free(mem_ptr);
+ return;
+}
+void * stAppRealloc (void *ptr, uint32 size, void *allocRef) {
+ return( realloc( ptr, size ) );
+}
+void * stAppCalloc (uint32 num, uint32 size, void *allocRef) {
+ return( calloc( num, size ) );
+}
+
+/*
+ * Ensure there's a connection to ctx->cspHand. If there
+ * already is one, fine.
+ * Note that as of 12/18/00, we assume we're connected to
+ * all modules all the time (since we do an attachToAll() in
+ * SSLNewContext()).
+ */
+OSStatus attachToCsp(SSLContext *ctx)
+{
+ assert(ctx != NULL);
+ if(ctx->cspHand != 0) {
+ return noErr;
+ }
+ else {
+ return errSSLModuleAttach;
+ }
+}
+
+/*
+ * Connect to TP, CL; reusable.
+ */
+OSStatus attachToCl(SSLContext *ctx)
+{
+ assert(ctx != NULL);
+ if(ctx->clHand != 0) {
+ return noErr;
+ }
+ else {
+ return errSSLModuleAttach;
+ }
+}
+
+OSStatus attachToTp(SSLContext *ctx)
+{
+ assert(ctx != NULL);
+ if(ctx->tpHand != 0) {
+ return noErr;
+ }
+ else {
+ return errSSLModuleAttach;
+ }
+}
+
+/*
+ * Convenience function - attach to CSP, CL, TP. Reusable.
+ */
+OSStatus attachToAll(SSLContext *ctx)
+{
+ CSSM_RETURN crtn;
+
+ assert(ctx != NULL);
+ crtn = attachToModules(&ctx->cspHand, &ctx->clHand, &ctx->tpHand);
+ if(crtn) {
+ return errSSLModuleAttach;
+ }
+ else {
+ return noErr;
+ }
+}
+
+OSStatus detachFromAll(SSLContext *ctx)
+{
+ #if 0
+ /* No more, attachments are kept on a global basis */
+ assert(ctx != NULL);
+ if(ctx->cspHand != 0) {
+ CSSM_ModuleDetach(ctx->cspHand);
+ ctx->cspHand = 0;
+ }
+ if(ctx->tpHand != 0) {
+ CSSM_ModuleDetach(ctx->tpHand);
+ ctx->tpHand = 0;
+ }
+ if(ctx->clHand != 0) {
+ CSSM_ModuleDetach(ctx->clHand);
+ ctx->clHand = 0;
+ }
+ #endif /* 0 */
+ return noErr;
+}
+
+#pragma mark -
+#pragma mark *** CSSM_DATA routines ***
+
+CSSM_DATA_PTR stMallocCssmData(
+ uint32 size)
+{
+ CSSM_DATA_PTR rtn = (CSSM_DATA_PTR)stAppMalloc(sizeof(CSSM_DATA), NULL);
+
+ if(rtn == NULL) {
+ return NULL;
+ }
+ rtn->Length = size;
+ if(size == 0) {
+ rtn->Data = NULL;
+ }
+ else {
+ rtn->Data = (uint8 *)stAppMalloc(size, NULL);
+ }
+ return rtn;
+}
+
+void stFreeCssmData(
+ CSSM_DATA_PTR data,
+ CSSM_BOOL freeStruct)
+{
+ if(data == NULL) {
+ return;
+ }
+ if(data->Data != NULL) {
+ stAppFree(data->Data, NULL);
+ data->Data = NULL;
+ }
+ data->Length = 0;
+ if(freeStruct) {
+ stAppFree(data, NULL);
+ }
+}
+
+/*
+ * Ensure that indicated CSSM_DATA_PTR can handle 'length' bytes of data.
+ * Malloc the Data ptr if necessary.
+ */
+OSStatus stSetUpCssmData(
+ CSSM_DATA_PTR data,
+ uint32 length)
+{
+ assert(data != NULL);
+ if(data->Length == 0) {
+ data->Data = (uint8 *)stAppMalloc(length, NULL);
+ if(data->Data == NULL) {
+ return memFullErr;
+ }
+ }
+ else if(data->Length < length) {
+ sslErrorLog("stSetUpCssmData: length too small\n");
+ return memFullErr;
+ }
+ data->Length = length;
+ return noErr;
+}
+
+#pragma mark -
+#pragma mark *** Public CSP Functions ***
+
+/*
+ * Raw RSA sign/verify.
+ *
+ * Initial X port: CSP doesns't support this, so we'll do sign/verify via
+ * raw RSA encrypt/decrypt here.
+ */
+#define SIGN_VFY_VIA_ENCR_DECR 0
+
+#if SIGN_VFY_VIA_ENCR_DECR
+
+OSStatus sslRsaRawSign(
+ SSLContext *ctx,
+ const CSSM_KEY *privKey,
+ CSSM_CSP_HANDLE cspHand,
+ const UInt8 *plainText,
+ UInt32 plainTextLen,
+ UInt8 *sig, // mallocd by caller; RETURNED
+ UInt32 sigLen, // available
+ UInt32 *actualBytes) // RETURNED
+{
+ /* Raw RSA sign with no digest is the same as raw RSA encrypt. */
+ /* Force CSSM_KEYUSE_ANY in case CL provided keyuse bits more specific
+ * than we really want */
+ OSStatus serr;
+ CSSM_KEYUSE savedKeyUse = privKey->KeyHeader.KeyUsage;
+ privKey->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
+ serr = sslRsaEncrypt(ctx,
+ privKey,
+ cspHand,
+ plainText,
+ plainTextLen,
+ sig,
+ sigLen,
+ actualBytes);
+ privKey->KeyHeader.KeyUsage = savedKeyUse;
+ return serr;
+}
+
+OSStatus sslRsaRawVerify(
+ SSLContext *ctx,
+ const CSSM_KEY *pubKey,
+ CSSM_CSP_HANDLE cspHand,
+ const UInt8 *plainText,
+ UInt32 plainTextLen,
+ const UInt8 *sig,
+ UInt32 sigLen)
+{
+ /*
+ * Raw RSA verify with no digest is just a comparison of the incoming
+ * plaintext with (signature, decrypted via raw RSA decrypt).
+ */
+
+ UInt32 actualBytes;
+ OSStatus serr;
+ UInt8 *digest;
+
+ /* Force CSSM_KEYUSE_ANY in case CL provided keyuse bits more specific
+ * than we really want */
+ CSSM_KEYUSE savedKeyUse = pubKey->KeyHeader.KeyUsage;
+ pubKey->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
+
+ /* malloc space for decrypting the signature */
+ digest = sslMalloc(plainTextLen);
+ if(digest == NULL) {
+ return memFullErr;
+ }
+
+ /* decrypt signature */
+ serr = sslRsaDecrypt(ctx,
+ pubKey,
+ cspHand,
+ sig,
+ sigLen,
+ digest,
+ plainTextLen,
+ &actualBytes);
+ pubKey->KeyHeader.KeyUsage = savedKeyUse;
+ if(serr) {
+ goto errOut;
+ }
+ if((actualBytes != plainTextLen) ||
+ (memcmp(plainText, digest, plainTextLen))) {
+ sslErrorLog("sslRsaRawVerify: sig miscompare\n");
+ serr = errSSLCrypto;
+ }
+ else {
+ serr = noErr;
+ }
+errOut:
+ sslFree(digest);
+ return serr;
+}
+
+#else /* OS9 and future post-cheetah version */
+
+OSStatus sslRsaRawSign(
+ SSLContext *ctx,
+ const CSSM_KEY *privKey,
+ CSSM_CSP_HANDLE cspHand,
+ const UInt8 *plainText,
+ UInt32 plainTextLen,
+ UInt8 *sig, // mallocd by caller; RETURNED
+ UInt32 sigLen, // available
+ UInt32 *actualBytes) // RETURNED
+{
+ CSSM_CC_HANDLE sigHand = 0;
+ CSSM_RETURN crtn;
+ OSStatus serr;
+ CSSM_DATA sigData;
+ CSSM_DATA ptextData;
+
+ assert(ctx != NULL);
+ if((privKey == NULL) ||
+ (cspHand == 0) ||
+ (plainText == NULL) ||
+ (sig == NULL) ||
+ (actualBytes == NULL)) {
+ sslErrorLog("sslRsaRawSign: bad arguments\n");
+ return errSSLInternal;
+ }
+ *actualBytes = 0;
+
+ crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+ CSSM_ALGID_RSA,
+ NULL, // passPhrase
+ privKey,
+ &sigHand);
+ if(crtn) {
+ stPrintCdsaError("CSSM_CSP_CreateSignatureContext (1)", crtn);
+ return errSSLCrypto;
+ }
+
+ ptextData.Data = (uint8 *)plainText;
+ ptextData.Length = plainTextLen;
+
+ /* caller better get this right, or the SignData will fail */
+ sigData.Data = sig;
+ sigData.Length = sigLen;
+
+ crtn = CSSM_SignData(sigHand,
+ &ptextData,
+ 1,
+ CSSM_ALGID_NONE, // digestAlg
+ &sigData);
+ if(crtn) {
+ stPrintCdsaError("CSSM_SignData", crtn);
+ serr = errSSLCrypto;
+ }
+ else {
+ *actualBytes = sigData.Length;
+ serr = noErr;
+ }
+ if(sigHand != 0) {
+ CSSM_DeleteContext(sigHand);
+ }
+ return serr;
+}
+
+OSStatus sslRsaRawVerify(
+ SSLContext *ctx,
+ const CSSM_KEY *pubKey,
+ CSSM_CSP_HANDLE cspHand,
+ const UInt8 *plainText,
+ UInt32 plainTextLen,
+ const UInt8 *sig,
+ UInt32 sigLen)
+{
+ CSSM_CC_HANDLE sigHand = 0;
+ CSSM_RETURN crtn;
+ OSStatus serr;
+ CSSM_DATA sigData;
+ CSSM_DATA ptextData;
+
+ assert(ctx != NULL);
+ if((pubKey == NULL) ||
+ (cspHand == 0) ||
+ (plainText == NULL) ||
+ (sig == NULL)) {
+ sslErrorLog("sslRsaRawVerify: bad arguments\n");
+ return errSSLInternal;
+ }
+
+ crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+ CSSM_ALGID_RSA,
+ NULL, // passPhrase
+ pubKey,
+ &sigHand);
+ if(sigHand == 0) {
+ stPrintCdsaError("CSSM_CSP_CreateSignatureContext (2)", crtn);
+ return errSSLCrypto;
+ }
+
+ ptextData.Data = (uint8 *)plainText;
+ ptextData.Length = plainTextLen;
+ sigData.Data = (uint8 *)sig;
+ sigData.Length = sigLen;
+
+ crtn = CSSM_VerifyData(sigHand,
+ &ptextData,
+ 1,
+ CSSM_ALGID_NONE, // digestAlg
+ &sigData);
+ if(crtn) {
+ stPrintCdsaError("CSSM_VerifyData", crtn);
+ serr = errSSLCrypto;
+ }
+ else {
+ serr = noErr;
+ }
+ if(sigHand != 0) {
+ CSSM_DeleteContext(sigHand);
+ }
+ return serr;
+}
+#endif /* SIGN_VFY_VIA_ENCR_DECR */
+
+/*
+ * Encrypt/Decrypt
+ */
+OSStatus sslRsaEncrypt(
+ SSLContext *ctx,
+ const CSSM_KEY *pubKey,
+ CSSM_CSP_HANDLE cspHand,
+ const UInt8 *plainText,
+ UInt32 plainTextLen,
+ UInt8 *cipherText, // mallocd by caller; RETURNED
+ UInt32 cipherTextLen, // available
+ UInt32 *actualBytes) // RETURNED
+{
+ CSSM_DATA ctextData = {0, NULL};
+ CSSM_DATA ptextData;
+ CSSM_DATA remData = {0, NULL};
+ CSSM_CC_HANDLE cryptHand = 0;
+ OSStatus serr = errSSLInternal;
+ CSSM_RETURN crtn;
+ uint32 bytesMoved = 0;
+ CSSM_ACCESS_CREDENTIALS creds;
+
+ assert(ctx != NULL);
+ assert(actualBytes != NULL);
+ *actualBytes = 0;
+
+ if((pubKey == NULL) || (cspHand == 0)) {
+ sslErrorLog("sslRsaEncrypt: bad pubKey/cspHand\n");
+ return errSSLInternal;
+ }
+
+ #if RSA_PUB_KEY_USAGE_HACK
+ ((CSSM_KEY_PTR)pubKey)->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT;
+ #endif
+ memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+
+ crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
+ CSSM_ALGID_RSA,
+ &creds,
+ pubKey,
+ CSSM_PADDING_PKCS1,
+ &cryptHand);
+ if(crtn) {
+ stPrintCdsaError("CSSM_CSP_CreateAsymmetricContext", crtn);
+ return errSSLCrypto;
+ }
+ ptextData.Data = (uint8 *)plainText;
+ ptextData.Length = plainTextLen;
+
+ if(pubKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY) {
+ /*
+ * Special case, encrypting with private key (i.e., raw sign). Add
+ * the required context attr.
+ */
+ CSSM_CONTEXT_ATTRIBUTE modeAttr;
+
+ modeAttr.AttributeType = CSSM_ATTRIBUTE_MODE;
+ modeAttr.AttributeLength = sizeof(uint32);
+ modeAttr.Attribute.Uint32 = CSSM_ALGMODE_PRIVATE_KEY;
+ crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &modeAttr);
+ if(crtn) {
+ stPrintCdsaError("CSSM_UpdateContextAttributes", crtn);
+ CSSM_DeleteContext(cryptHand);
+ return errSSLCrypto;
+ }
+ }
+
+ /*
+ * Have CSP malloc ciphertext
+ */
+ crtn = CSSM_EncryptData(cryptHand,
+ &ptextData,
+ 1,
+ &ctextData,
+ 1,
+ &bytesMoved,
+ &remData);
+ if(crtn == CSSM_OK) {
+ /*
+ * ciphertext in both ctextData and remData; ensure it'll fit
+ * in caller's buf & copy
+ */
+ if(bytesMoved > cipherTextLen) {
+ sslErrorLog("sslRsaEncrypt overflow; cipherTextLen %ld bytesMoved %ld\n",
+ cipherTextLen, bytesMoved);
+ serr = errSSLCrypto;
+ }
+ else {
+ UInt32 toMoveCtext;
+ UInt32 toMoveRem;
+
+ *actualBytes = bytesMoved;
+ /*
+ * Snag valid data from ctextData - its length or bytesMoved,
+ * whichever is less
+ */
+ if(ctextData.Length > bytesMoved) {
+ /* everything's in ctext */
+ toMoveCtext = bytesMoved;
+ toMoveRem = 0;
+ }
+ else {
+ /* must be some in remData too */
+ toMoveCtext = ctextData.Length;
+ toMoveRem = bytesMoved - toMoveCtext; // remainder
+ }
+ if(toMoveCtext) {
+ memmove(cipherText, ctextData.Data, toMoveCtext);
+ }
+ if(toMoveRem) {
+ memmove(cipherText + toMoveCtext, remData.Data,
+ toMoveRem);
+ }
+ serr = noErr;
+ }
+ }
+ else {
+ stPrintCdsaError("CSSM_EncryptData", crtn);
+ serr = errSSLCrypto;
+ }
+ if(cryptHand != 0) {
+ CSSM_DeleteContext(cryptHand);
+ }
+
+ /* free data mallocd by CSP */
+ stFreeCssmData(&ctextData, CSSM_FALSE);
+ stFreeCssmData(&remData, CSSM_FALSE);
+ return serr;
+}
+
+OSStatus sslRsaDecrypt(
+ SSLContext *ctx,
+ const CSSM_KEY *privKey,
+ CSSM_CSP_HANDLE cspHand,
+ const UInt8 *cipherText,
+ UInt32 cipherTextLen,
+ UInt8 *plainText, // mallocd by caller; RETURNED
+ UInt32 plainTextLen, // available
+ UInt32 *actualBytes) // RETURNED
+{
+ CSSM_DATA ptextData = {0, NULL};
+ CSSM_DATA ctextData;
+ CSSM_DATA remData = {0, NULL};
+ CSSM_CC_HANDLE cryptHand = 0;
+ OSStatus serr = errSSLInternal;
+ CSSM_RETURN crtn;
+ uint32 bytesMoved = 0;
+ CSSM_ACCESS_CREDENTIALS creds;
+
+ assert(ctx != NULL);
+ assert(actualBytes != NULL);
+ *actualBytes = 0;
+
+ if((privKey == NULL) || (cspHand == 0)) {
+ sslErrorLog("sslRsaDecrypt: bad privKey/cspHand\n");
+ return errSSLInternal;
+ }
+ memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+ crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
+ CSSM_ALGID_RSA,
+ &creds,
+ privKey,
+ CSSM_PADDING_PKCS1,
+ &cryptHand);
+ if(crtn) {
+ stPrintCdsaError("CSSM_CSP_CreateAsymmetricContext", crtn);
+ return errSSLCrypto;
+ }
+ ctextData.Data = (uint8 *)cipherText;
+ ctextData.Length = cipherTextLen;
+
+ if(privKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PUBLIC_KEY) {
+ /*
+ * Special case, decrypting with public key (i.e., raw verify). Add
+ * the required context attr.
+ */
+ CSSM_CONTEXT_ATTRIBUTE modeAttr;
+
+ modeAttr.AttributeType = CSSM_ATTRIBUTE_MODE;
+ modeAttr.AttributeLength = sizeof(uint32);
+ modeAttr.Attribute.Uint32 = CSSM_ALGMODE_PUBLIC_KEY;
+ crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &modeAttr);
+ if(crtn) {
+ stPrintCdsaError("CSSM_UpdateContextAttributes", crtn);
+ CSSM_DeleteContext(cryptHand);
+ return errSSLCrypto;
+ }
+ }
+
+ /*
+ * Have CSP malloc plaintext
+ */
+ crtn = CSSM_DecryptData(cryptHand,
+ &ctextData,
+ 1,
+ &ptextData,
+ 1,
+ &bytesMoved,
+ &remData);
+ if(crtn == CSSM_OK) {
+ /*
+ * plaintext in both ptextData and remData; ensure it'll fit
+ * in caller's buf & copy
+ */
+ if(bytesMoved > plainTextLen) {
+ sslErrorLog("sslRsaDecrypt overflow; plainTextLen %ld bytesMoved %ld\n",
+ plainTextLen, bytesMoved);
+ serr = errSSLCrypto;
+ }
+ else {
+ UInt32 toMovePtext;
+ UInt32 toMoveRem;
+
+ *actualBytes = bytesMoved;
+ /*
+ * Snag valid data from ptextData - its length or bytesMoved,
+ * whichever is less
+ */
+ if(ptextData.Length > bytesMoved) {
+ /* everything's in ptext */
+ toMovePtext = bytesMoved;
+ toMoveRem = 0;
+ }
+ else {
+ /* must be some in remData too */
+ toMovePtext = ptextData.Length;
+ toMoveRem = bytesMoved - toMovePtext; // remainder
+ }
+ if(toMovePtext) {
+ memmove(plainText, ptextData.Data, toMovePtext);
+ }
+ if(toMoveRem) {
+ memmove(plainText + toMovePtext, remData.Data,
+ toMoveRem);
+ }
+ serr = noErr;
+ }
+ }
+ else {
+ stPrintCdsaError("CSSM_DecryptData", crtn);
+ serr = errSSLCrypto;
+ }
+ if(cryptHand != 0) {
+ CSSM_DeleteContext(cryptHand);
+ }
+
+ /* free data mallocd by CSP */
+ stFreeCssmData(&ptextData, CSSM_FALSE);
+ stFreeCssmData(&remData, CSSM_FALSE);
+ return serr;
+}
+
+/*
+ * Obtain size of key in bytes.
+ */
+UInt32 sslKeyLengthInBytes(const CSSM_KEY *key)
+{
+ assert(key != NULL);
+ return (((key->KeyHeader.LogicalKeySizeInBits) + 7) / 8);
+}
+
+/*
+ * Get raw key bits from an RSA public key.
+ */
+OSStatus sslGetPubKeyBits(
+ SSLContext *ctx,
+ const CSSM_KEY *pubKey,
+ CSSM_CSP_HANDLE cspHand,
+ SSLBuffer *modulus, // data mallocd and RETURNED
+ SSLBuffer *exponent) // data mallocd and RETURNED
+{
+ CSSM_KEY wrappedKey;
+ CSSM_BOOL didWrap = CSSM_FALSE;
+ const CSSM_KEYHEADER *hdr;
+ CSSM_CC_HANDLE ccHand;
+ CSSM_RETURN crtn;
+ SSLBuffer pubKeyBlob;
+ OSStatus srtn;
+ CSSM_ACCESS_CREDENTIALS creds;
+
+ assert(ctx != NULL);
+ assert(modulus != NULL);
+ assert(exponent != NULL);
+ assert(pubKey != NULL);
+
+ hdr = &pubKey->KeyHeader;
+ if(hdr->KeyClass != CSSM_KEYCLASS_PUBLIC_KEY) {
+ sslErrorLog("sslGetPubKeyBits: bad keyClass (%ld)\n", hdr->KeyClass);
+ return errSSLInternal;
+ }
+ if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
+ sslErrorLog("sslGetPubKeyBits: bad AlgorithmId (%ld)\n", hdr->AlgorithmId);
+ return errSSLInternal;
+ }
+
+ /*
+ * Handle possible reference format - I think it should be in
+ * blob form since it came from the DL, but conversion is
+ * simple.
+ */
+ switch(hdr->BlobType) {
+ case CSSM_KEYBLOB_RAW:
+ /* easy case */
+ CSSM_TO_SSLBUF(&pubKey->KeyData, &pubKeyBlob);
+ break;
+
+ case CSSM_KEYBLOB_REFERENCE:
+ /*
+ * Convert to a blob via "NULL wrap"; no wrapping key,
+ * ALGID_NONE
+ */
+ srtn = attachToCsp(ctx);
+ if(srtn) {
+ return srtn;
+ }
+ memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+ crtn = CSSM_CSP_CreateSymmetricContext(ctx->cspHand,
+ CSSM_ALGID_NONE,
+ CSSM_ALGMODE_NONE,
+ &creds, // creds
+ pubKey,
+ NULL, // InitVector
+ CSSM_PADDING_NONE,
+ 0, // reserved
+ &ccHand);
+ if(crtn) {
+ stPrintCdsaError("sslGetPubKeyBits: CreateSymmetricContext failure", crtn);
+ return errSSLCrypto;
+ }
+ memset(&wrappedKey, 0, sizeof(CSSM_KEY));
+ crtn = CSSM_WrapKey(ccHand,
+ &creds,
+ pubKey,
+ NULL, // descriptiveData
+ &wrappedKey);
+ CSSM_DeleteContext(ccHand);
+ if(crtn) {
+ stPrintCdsaError("CSSM_WrapKey", crtn);
+ return errSSLCrypto;
+ }
+ hdr = &wrappedKey.KeyHeader;
+ if(hdr->BlobType != CSSM_KEYBLOB_RAW) {
+ sslErrorLog("sslGetPubKeyBits: bad BlobType (%ld) after WrapKey\n",
+ hdr->BlobType);
+ return errSSLCrypto;
+ }
+ didWrap = CSSM_TRUE;
+ CSSM_TO_SSLBUF(&wrappedKey.KeyData, &pubKeyBlob);
+ break;
+
+ default:
+ sslErrorLog("sslGetPubKeyBits: bad BlobType (%ld)\n",
+ hdr->BlobType);
+ return errSSLInternal;
+
+ } /* switch BlobType */
+
+ assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
+ srtn = sslDecodeRsaBlob(&pubKeyBlob, modulus, exponent);
+ if(didWrap) {
+ CSSM_FreeKey(ctx->cspHand, NULL, &wrappedKey, CSSM_FALSE);
+ }
+ return srtn;
+}
+
+/*
+ * Given raw RSA key bits, cook up a CSSM_KEY_PTR. Used in
+ * Server-initiated key exchange.
+ */
+OSStatus sslGetPubKeyFromBits(
+ SSLContext *ctx,
+ const SSLBuffer *modulus,
+ const SSLBuffer *exponent,
+ CSSM_KEY_PTR *pubKey, // mallocd and RETURNED
+ CSSM_CSP_HANDLE *cspHand) // RETURNED
+{
+ CSSM_KEY_PTR key = NULL;
+ OSStatus serr;
+ SSLBuffer blob;
+ CSSM_KEYHEADER_PTR hdr;
+ CSSM_KEY_SIZE keySize;
+ CSSM_RETURN crtn;
+
+ assert((ctx != NULL) && (modulus != NULL) && (exponent != NULL));
+ assert((pubKey != NULL) && (cspHand != NULL));
+
+ *pubKey = NULL;
+ *cspHand = 0;
+
+ serr = attachToCsp(ctx);
+ if(serr) {
+ return serr;
+ }
+ serr = sslEncodeRsaBlob(modulus, exponent, &blob);
+ if(serr) {
+ return serr;
+ }
+
+ /* the rest is boilerplate, cook up a good-looking public key */
+ key = (CSSM_KEY_PTR)sslMalloc(sizeof(CSSM_KEY));
+ if(key == NULL) {
+ return memFullErr;
+ }
+ memset(key, 0, sizeof(CSSM_KEY));
+ hdr = &key->KeyHeader;
+
+ hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
+ /* key_ptr->KeyHeader.CspId is unknown (remains 0) */
+ hdr->BlobType = CSSM_KEYBLOB_RAW;
+ hdr->AlgorithmId = CSSM_ALGID_RSA;
+ hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
+ hdr->KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+ /* comply with ASA requirements */
+ hdr->KeyUsage = CSSM_KEYUSE_VERIFY;
+ hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
+ /* key_ptr->KeyHeader.StartDate is unknown (remains 0) */
+ /* key_ptr->KeyHeader.EndDate is unknown (remains 0) */
+ hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
+ hdr->WrapMode = CSSM_ALGMODE_NONE;
+
+ /* blob->data was mallocd by sslEncodeRsaBlob, pass it over to
+ * actual key */
+ SSLBUF_TO_CSSM(&blob, &key->KeyData);
+
+ /*
+ * Get keySizeInBits. This also serves to validate the key blob
+ * we just cooked up.
+ */
+ crtn = CSSM_QueryKeySizeInBits(ctx->cspHand, CSSM_INVALID_HANDLE, key, &keySize);
+ if(crtn) {
+ stPrintCdsaError("sslGetPubKeyFromBits: QueryKeySizeInBits\n", crtn);
+ serr = errSSLCrypto;
+ goto abort;
+ }
+
+ /* success */
+ hdr->LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits;
+ *pubKey = key;
+ *cspHand = ctx->cspHand;
+ return noErr;
+
+abort:
+ /* note this frees the blob */
+ sslFreeKey(ctx->cspHand, &key, NULL);
+ return serr;
+}
+
+#pragma mark -
+#pragma mark *** Public Certificate Functions ***
+
+/*
+ * Given a DER-encoded cert, obtain its public key as a CSSM_KEY_PTR.
+ * Caller must CSSM_FreeKey and free the CSSM_KEY_PTR itself.
+ *
+ * For now, the returned cspHand is a copy of ctx->cspHand, so it
+ * doesn't have to be detached later - this may change.
+ *
+ * Update: since CSSM_CL_CertGetKeyInfo() doesn't provide a means for
+ * us to tell the CL what CSP to use, we really have no way of knowing
+ * what is going on here...we return the process-wide (bare) cspHand,
+ * which is currently always able to deal with this raw public key.
+ */
+OSStatus sslPubKeyFromCert(
+ SSLContext *ctx,
+ const SSLBuffer &derCert,
+ CSSM_KEY_PTR *pubKey, // RETURNED
+ CSSM_CSP_HANDLE *cspHand) // RETURNED
+{
+ OSStatus serr;
+ CSSM_DATA certData;
+ CSSM_RETURN crtn;
+
+ assert(ctx != NULL);
+ assert(pubKey != NULL);
+ assert(cspHand != NULL);
+
+ *pubKey = NULL;
+ *cspHand = 0;
+
+ serr = attachToCl(ctx);
+ if(serr) {
+ return serr;
+ }
+ serr = attachToCsp(ctx);
+ if(serr) {
+ return serr;
+ }
+ SSLBUF_TO_CSSM(&derCert, &certData);
+ crtn = CSSM_CL_CertGetKeyInfo(ctx->clHand, &certData, pubKey);
+ if(crtn) {
+ return errSSLBadCert;
+ }
+ else {
+ *cspHand = ctx->cspHand;
+ return noErr;
+ }
+}
+
+#if ST_MANAGES_TRUSTED_ROOTS
+
+/*
+ * Given a CSSM_CERTGROUP which fails due to CSSM_TP_INVALID_ANCHOR
+ * (chain verifies to an unknown root):
+ *
+ * -- find the root cert
+ * -- add it to newRootCertKc if present (else error)
+ * -- add it to trustedCerts
+ * -- re-verify certgroup, demand full success
+ */
+static OSStatus sslHandleNewRoot(
+ SSLContext *ctx,
+ CSSM_CERTGROUP_PTR certGroup)
+{
+ int i;
+ CSSM_DATA_PTR rootCert;
+ CSSM_BOOL expired;
+ OSStatus serr;
+ CSSM_BOOL brtn;
+
+ assert(ctx != NULL);
+ assert(certGroup != NULL);
+
+ if(ctx->newRootCertKc == NULL) {
+ /* no place to add this; done */
+ return errSSLUnknownRootCert;
+ }
+
+ /*
+ * The root cert "should" be at the end of the chain, but
+ * let's not assume that. (We are assuming that there is
+ * only one root in the cert group...)
+ */
+ for(i=0; i<certGroup->NumCerts; i++) {
+ rootCert = &certGroup->CertList[i];
+ if(sslVerifyCert(ctx, rootCert, rootCert, ctx->cspHand, &expired)) {
+ break;
+ }
+ }
+ if(i == certGroup->NumCerts) {
+ /* Huh! no root cert!? We should not have been called! */
+ sslErrorLog("sslHandleNewRoot: no root cert!\n");
+ return errSSLInternal;
+ }
+
+ /*
+ * Add to newRootCertKc. This may well fail due to user interaction.
+ */
+ serr = sslAddNewRoot(ctx, rootCert);
+ if(serr) {
+ return serr;
+ }
+
+ /*
+ * Just to be sure...reverify the whole cert chain.
+ */
+ brtn = CSSM_TP_CertGroupVerify(
+ ctx->tpHand,
+ ctx->clHand,
+ ctx->cspHand,
+ NULL, // DBList
+ NULL, // PolicyIdentifiers
+ 0, // NumberofPolicyIdentifiers
+ CSSM_TP_STOP_ON_POLICY,
+ certGroup,
+ ctx->trustedCerts, // AnchorCerts
+ ctx->numTrustedCerts,
+ NULL, // VerifyScope
+ 0, // ScopeSize
+ 0, // Action
+ 0, // Data
+ NULL, // evidence
+ NULL); // evidenceSize
+ if(brtn == CSSM_FALSE) {
+ sslErrorLog("sslHandleNewRoot: adding new root did not help!\n");
+ return errSSLUnknownRootCert;
+ }
+ return noErr;
+}
+
+#endif /* ST_MANAGES_TRUSTED_ROOTS */
+
+/*
+ * Verify a chain of DER-encoded certs.
+ * First cert in a chain is root; this must also be present
+ * in ctx->trustedCerts.
+ */
+OSStatus sslVerifyCertChain(
+ SSLContext *ctx,
+ const SSLCertificate &certChain,
+ bool verifyHostName /* = true */)
+{
+ UInt32 numCerts;
+ CSSM_CERTGROUP certGroup;
+ int i;
+ OSStatus serr;
+ SSLCertificate *c = (SSLCertificate *)&certChain;
+ CSSM_RETURN crtn;
+ CSSM_TP_VERIFY_CONTEXT vfyCtx;
+ CSSM_TP_CALLERAUTH_CONTEXT authCtx;
+ CSSM_FIELD policyId;
+ CSSM_DL_DB_LIST dbList;
+ CSSM_APPLE_TP_SSL_OPTIONS sslOpts;
+ CSSM_APPLE_TP_ACTION_DATA actionData;
+
+ if(!ctx->enableCertVerify) {
+ /* trivial case, this is caller's responsibility */
+ return noErr;
+ }
+ numCerts = SSLGetCertificateChainLength(&certChain);
+ if(numCerts == 0) {
+ /* nope */
+ return errSSLBadCert;
+ }
+ #if 0
+ serr = attachToAll(ctx);
+ if(serr) {
+ return serr;
+ }
+ #endif
+
+ /*
+ * SSLCertificate chain --> CSSM TP cert group.
+ * TP Cert group has root at the end, opposite of
+ * SSLCertificate chain.
+ */
+ certGroup.GroupList.CertList =
+ (CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA));
+ if(certGroup.GroupList.CertList == NULL) {
+ return memFullErr;
+ }
+ certGroup.CertGroupType = CSSM_CERTGROUP_DATA;
+ certGroup.CertType = CSSM_CERT_X_509v3;
+ certGroup.CertEncoding = CSSM_CERT_ENCODING_DER;
+ certGroup.NumCerts = numCerts;
+
+ memset(certGroup.GroupList.CertList, 0, numCerts * sizeof(CSSM_DATA));
+
+ for(i=numCerts-1; i>=0; i--) {
+ SSLBUF_TO_CSSM(&c->derCert, &certGroup.GroupList.CertList[i]);
+ c = c->next;
+ }
+
+ memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT));
+ vfyCtx.Action = CSSM_TP_ACTION_DEFAULT;
+ vfyCtx.Cred = &authCtx;
+
+ /* CSSM_TP_CALLERAUTH_CONTEXT components */
+ /*
+ typedef struct cssm_tp_callerauth_context {
+ CSSM_TP_POLICYINFO Policy;
+ CSSM_TIMESTRING VerifyTime;
+ CSSM_TP_STOP_ON VerificationAbortOn;
+ CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert;
+ uint32 NumberOfAnchorCerts;
+ CSSM_DATA_PTR AnchorCerts;
+ CSSM_DL_DB_LIST_PTR DBList;
+ CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials;
+ } CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR;
+ */
+
+ /* SSL-specific FieldValue */
+ sslOpts.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
+ if(verifyHostName) {
+ sslOpts.ServerNameLen = ctx->peerDomainNameLen;
+ sslOpts.ServerName = ctx->peerDomainName;
+ }
+ else {
+ sslOpts.ServerNameLen = 0;
+ sslOpts.ServerName = NULL;
+ }
+
+ /* TP-wide ActionData */
+ actionData.Version = CSSM_APPLE_TP_ACTION_VERSION;
+ if(ctx->numTrustedCerts != 0) {
+ /* use our anchors */
+ actionData.ActionFlags = 0;
+ }
+ else {
+ /* secret root-cert-enable */
+ actionData.ActionFlags = 0x80000000;
+ }
+ if(ctx->allowExpiredCerts) {
+ actionData.ActionFlags |= CSSM_TP_ACTION_ALLOW_EXPIRED;
+ }
+ if(ctx->allowExpiredRoots) {
+ actionData.ActionFlags |= CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT;
+ }
+ vfyCtx.ActionData.Data = (uint8 *)&actionData;
+ vfyCtx.ActionData.Length = sizeof(actionData);
+
+ /* zero or one policy here */
+ policyId.FieldOid = CSSMOID_APPLE_TP_SSL;
+ policyId.FieldValue.Data = (uint8 *)&sslOpts;
+ policyId.FieldValue.Length = sizeof(sslOpts);
+ authCtx.Policy.NumberOfPolicyIds = 1;
+ authCtx.Policy.PolicyIds = &policyId;
+
+ authCtx.VerifyTime = NULL;
+ authCtx.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY;
+ authCtx.CallbackWithVerifiedCert = NULL;
+ authCtx.NumberOfAnchorCerts = ctx->numTrustedCerts;
+ authCtx.AnchorCerts = ctx->trustedCerts;
+ memset(&dbList, 0, sizeof(CSSM_DL_DB_LIST));
+ authCtx.DBList = &dbList;
+ authCtx.CallerCredentials = NULL;
+
+ /*
+ * Here we go; hand it over to TP. Note trustedCerts are our
+ * known good Anchor certs; they're already formatted properly.
+ * Unlike most other Apple code, we demand full success here,
+ * implying that the last cert in the chain is indeed an Anchor
+ * cert. We already know that all of our anchor certs are
+ * roots, so on successful return, we'll know the incoming
+ * chain has a root, it verifies to that root, and that that
+ * root is in trustedCerts.
+ */
+ crtn = CSSM_TP_CertGroupVerify(ctx->tpHand,
+ ctx->clHand,
+ ctx->cspHand,
+ &certGroup,
+ &vfyCtx,
+ NULL); // no evidence needed
+
+ serr = noErr;
+ if(crtn) {
+ /* get some detailed error info */
+ switch(crtn) {
+ case CSSMERR_TP_INVALID_ANCHOR_CERT:
+ /* root found but we don't trust it */
+ if(ctx->allowAnyRoot) {
+ sslErrorLog("***Warning: accepting unknown root cert\n");
+ break;
+ }
+ #if ST_MANAGES_TRUSTED_ROOTS
+ if(ctx->newRootCertKc != NULL) {
+ /* see if user wants to handle new root */
+ serr = sslHandleNewRoot(ctx, &certGroup);
+ }
+ else {
+ serr = errSSLUnknownRootCert;
+ }
+ #else
+ serr = errSSLUnknownRootCert;
+ #endif /* ST_MANAGES_TRUSTED_ROOTS */
+ break;
+ case CSSMERR_TP_NOT_TRUSTED:
+ /* no root, not even in implicit SSL roots */
+ if(ctx->allowAnyRoot) {
+ sslErrorLog("***Warning: accepting unverified cert chain\n");
+ break;
+ }
+ serr = errSSLNoRootCert;
+ break;
+ case CSSMERR_TP_CERT_EXPIRED:
+ assert(!ctx->allowExpiredCerts);
+ serr = errSSLCertExpired;
+ break;
+ case CSSMERR_TP_CERT_NOT_VALID_YET:
+ serr = errSSLCertNotYetValid;
+ break;
+ default:
+ stPrintCdsaError(
+ "sslVerifyCertChain: CSSM_TP_CertGroupVerify returned", crtn);
+ serr = errSSLXCertChainInvalid;
+ break;
+ }
+ } /* brtn FALSE */
+
+ /*
+ * don't free individual certs - caller still owns them
+ * don't free struct - on stack
+ */
+ sslFree(certGroup.GroupList.CertList);
+ return serr;
+}
+
+#if ST_MANAGES_TRUSTED_ROOTS
+
+/*
+ * Given a DER-encoded cert, obtain its DER-encoded subject name.
+ */
+CSSM_DATA_PTR sslGetCertSubjectName(
+ SSLContext *ctx,
+ const CSSM_DATA_PTR cert)
+{
+ uint32 NumberOfFields = 0;
+ CSSM_HANDLE ResultsHandle = 0;
+ CSSM_DATA_PTR pEncodedName = NULL;
+ CSSM_RETURN crtn;
+
+ /* ensure connection to CL */
+ if(attachToCl(ctx)) {
+ return NULL;
+ }
+ crtn = CSSM_CL_CertGetFirstFieldValue(
+ ctx->clHand,
+ cert,
+ &CSSMOID_X509V1SubjectName,
+ &ResultsHandle,
+ &NumberOfFields,
+ &pEncodedName);
+ if(crtn) {
+ stPrintCdsaError("CertGetFirstFieldValue", crtn);
+ }
+ CSSM_CL_CertAbortQuery(ctx->clHand, ResultsHandle);
+ return pEncodedName;
+}
+#endif /* ST_MANAGES_TRUSTED_ROOTS */
+
+#if (SSL_DEBUG && ST_MANAGES_TRUSTED_ROOTS)
+void verifyTrustedRoots(SSLContext *ctx,
+ CSSM_DATA_PTR certs,
+ unsigned numCerts)
+{
+ int i;
+ CSSM_DATA_PTR cert;
+ CSSM_BOOL expired;
+
+ for(i=0; i<numCerts; i++) {
+ cert = &certs[i];
+ if(!sslVerifyCert(ctx,
+ cert,
+ cert,
+ ctx->cspHand,
+ &expired)) {
+ sslErrorLog("Bad trusted cert!\n");
+ }
+ }
+}
+#endif
+
+#ifndef NDEBUG
+void stPrintCdsaError(const char *op, CSSM_RETURN crtn)
+{
+ cssmPerror(op, crtn);
+}
+
+char *stCssmErrToStr(CSSM_RETURN err)
+{
+ string errStr = cssmErrorString(err);
+ return const_cast<char *>(errStr.c_str());
+}
+#endif
+
+
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: appleGlue.c
-
- Contains: Glue layer between Apple SecureTransport and
- original SSLRef code.
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-#ifndef _SSL_H_
-#include "ssl.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _APPLE_GLUE_H_
-#include "appleGlue.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-#include <time.h>
-#include <string.h>
-
-/*
- * Cruft used to map between private SSLErr's and the SSL-specific
- * OSStatus values in SecureTransport.h. Eventually we should do
- * away with SSLErr....
- */
-typedef struct {
- SSLErr serr;
- OSStatus oerr;
-} _sslErrMap;
-
-static const _sslErrMap sslErrMap[] = {
- { SSLNoErr, noErr },
- { SSLMemoryErr, memFullErr },
- { SSLUnsupportedErr, unimpErr },
- { SSLProtocolErr, errSSLProtocol },
- { SSLNegotiationErr, errSSLNegotiation },
- { SSLFatalAlert, errSSLFatalAlert },
- { SSLWouldBlockErr, errSSLWouldBlock },
- { SSLIOErr, ioErr },
- { SSLSessionNotFoundErr, errSSLSessionNotFound },
- { SSLConnectionClosedGraceful, errSSLClosedGraceful },
- { SSLConnectionClosedError, errSSLClosedAbort },
- { X509CertChainInvalidErr, errSSLXCertChainInvalid },
- { SSLBadCert, errSSLBadCert },
- { SSLCryptoError, errSSLCrypto },
- { SSLInternalError, errSSLInternal },
- { SSLDataOverflow, errSSLCrypto },
- { SSLAttachFailure, errSSLModuleAttach },
- { SSLUnknownRootCert, errSSLUnknownRootCert },
- { SSLNoRootCert, errSSLNoRootCert },
- { SSLCertExpired, errSSLCertExpired },
- { SSLCertNotYetValid, errSSLCertNotYetValid },
- { SSLBadStateErr, badReqErr },
- { SSLConnectionClosedNoNotify, errSSLClosedNoNotify },
-};
-
-#define SIZEOF_ERR_MAP (sizeof(sslErrMap) / sizeof(_sslErrMap))
-
-/*
- * Functions to allow old code to use SSLBuffer-based I/O calls.
- * We redirect the calls here to an SSL{Write,Read}Func.
- * This is of course way inefficient due to an extra copy for
- * each I/O, but let's do it this way until the port settles down.
- */
-SSLErr sslIoRead(
- SSLBuffer buf,
- size_t *actualLength,
- SSLContext *ctx)
- {
- UInt32 dataLength = buf.length;
- OSStatus ortn;
-
- *actualLength = 0;
- ortn = (ctx->ioCtx.read)(ctx->ioCtx.ioRef,
- buf.data,
- &dataLength);
- *actualLength = dataLength;
- return sslErrFromOsStatus(ortn);
- }
-
- SSLErr sslIoWrite(
- SSLBuffer buf,
- size_t *actualLength,
- SSLContext *ctx)
- {
- UInt32 dataLength = buf.length;
- OSStatus ortn;
-
- *actualLength = 0;
- ortn = (ctx->ioCtx.write)(ctx->ioCtx.ioRef,
- buf.data,
- &dataLength);
- *actualLength = dataLength;
- return sslErrFromOsStatus(ortn);
- }
-
- /*
- * Convert between SSLErr and OSStatus.
- * These will go away eventually.
- */
-SSLErr sslErrFromOsStatus(OSStatus o)
-{
- int i;
- const _sslErrMap *emap = sslErrMap;
-
- for(i=0; i<SIZEOF_ERR_MAP; i++) {
- if(emap->oerr == o) {
- return emap->serr;
- }
- emap++;
- }
- return SSLIOErr; /* normal: bad error */
-}
-
-OSStatus sslErrToOsStatus(SSLErr s)
-{
- int i;
- const _sslErrMap *emap = sslErrMap;
-
- for(i=0; i<SIZEOF_ERR_MAP; i++) {
- if(emap->serr == s) {
- return emap->oerr;
- }
- emap++;
- }
- CASSERT(0); /* Debug: panic */
- return paramErr; /* normal: bad error */
-}
-
-/*
- * Time functions - replaces SSLRef's SSLTimeFunc, SSLConvertTimeFunc
- */
-SSLErr sslTime(UInt32 *tim)
-{
- time_t t;
- time(&t);
- *tim = (UInt32)t;
- return SSLNoErr;
-}
-
-#ifdef notdef
-/* not used.... */
-SSLErr sslConvertTime(UInt32 *time)
-{
- return SSLUnsupportedErr;
-}
-#endif
Contains: Session storage module, Apple CDSA version.
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
*/
/*
- * This file replaces the caller-specified SSLAddSessionFunc,
- * SSLGetSessionFunc, and SSLDeleteSessionFunc callbacks in the
- * original SSLRef 3.0.
- *
* The current implementation stores sessions in a deque<>, a member of a
* SessionCache object for which we keep a ModuleNexus-ized instance. It is
* expected that at a given time, only a small number of sessions will be
*/
#include "ssl.h"
-//#include "sslctx.h"
-#include "sslalloc.h"
-#include "appleGlue.h"
+#include "sslMemory.h"
#include "sslDebug.h"
#include "appleSession.h"
#define CACHE_PRINT 0
#if CACHE_PRINT
-#define cprintf(s) printf s
#define DUMP_ALL_CACHE 0
static void cachePrint(
}
}
#else /* !CACHE_PRINT */
-#define cprintf(s)
#define cachePrint(k, d)
#define DUMP_ALL_CACHE 0
#endif /* CACHE_PRINT */
SSLBuffer &sessionData() { return mSessionData; }
/* replace existing mSessionData */
- SSLErr sessionData(const SSLBuffer &data);
+ OSStatus sessionData(const SSLBuffer &data);
private:
SSLBuffer mKey;
const Time::Absolute &expirationTime)
: mExpiration(expirationTime)
{
- SSLErr serr;
+ OSStatus serr;
- serr = SSLCopyBuffer(&key, &mKey);
+ serr = SSLCopyBuffer(key, mKey);
if(serr) {
throw runtime_error("memory error");
}
- serr = SSLCopyBuffer(&sessionData, &mSessionData);
+ serr = SSLCopyBuffer(sessionData, mSessionData);
if(serr) {
throw runtime_error("memory error");
}
- cprintf(("SessionCacheEntry(buf,buf) this %p\n", this));
+ sslLogSessCacheDebug("SessionCacheEntry(buf,buf) this %p", this);
mExpiration += Time::Interval(SESSION_CACHE_TTL);
}
SessionCacheEntry::~SessionCacheEntry()
{
- cprintf(("~SessionCacheEntry() this %p\n", this));
- SSLFreeBuffer(&mKey, NULL); // no SystemContext
- SSLFreeBuffer(&mSessionData, NULL);
+ sslLogSessCacheDebug("~SessionCacheEntry() this %p", this);
+ SSLFreeBuffer(mKey, NULL); // no SSLContext
+ SSLFreeBuffer(mSessionData, NULL);
}
/* basic lookup/match function */
}
/* replace existing mSessionData */
-SSLErr SessionCacheEntry::sessionData(
+OSStatus SessionCacheEntry::sessionData(
const SSLBuffer &data)
{
- SSLFreeBuffer(&mSessionData, NULL);
- return SSLCopyBuffer(&data, &mSessionData);
+ SSLFreeBuffer(mSessionData, NULL);
+ return SSLCopyBuffer(data, mSessionData);
}
/* Types for the actual deque and its iterator */
~SessionCache();
/* these correspond to the C functions exported by this file */
- SSLErr addEntry(
+ OSStatus addEntry(
const SSLBuffer sessionKey,
const SSLBuffer sessionData);
- SSLErr lookupEntry(
+ OSStatus lookupEntry(
const SSLBuffer sessionKey,
SSLBuffer *sessionData);
- SSLErr deleteEntry(
+ OSStatus deleteEntry(
const SSLBuffer sessionKey);
/* cleanup, delete stale entries */
}
/* these three correspond to the C functions exported by this file */
-SSLErr SessionCache::addEntry(
+OSStatus SessionCache::addEntry(
const SSLBuffer sessionKey,
const SSLBuffer sessionData)
{
* These usually match, and a memcmp is a lot cheaper than
* a malloc and a free, hence this quick optimization.....
*/
- cprintf(("SessionCache::addEntry CACHE HIT entry = %p\n", existEntry));
- return SSLNoErr;
+ sslLogSessCacheDebug("SessionCache::addEntry CACHE HIT "
+ "entry = %p", existEntry);
+ return noErr;
}
else {
- cprintf(("SessionCache::addEntry CACHE REPLACE entry = %p\n", existEntry));
+ sslLogSessCacheDebug("SessionCache::addEntry CACHE REPLACE "
+ "entry = %p", existEntry);
return existEntry->sessionData(sessionData);
}
}
sessionData,
Time::now() + mTimeToLive);
- cprintf(("SessionCache::addEntry %p\n", entry));
+ sslLogSessCacheDebug("SessionCache::addEntry %p", entry);
cachePrint(&sessionKey, &sessionData);
dumpAllCache();
/* add to head of queue for LIFO caching */
mSessionCache.push_front(entry);
- CASSERT(lookupPriv(&sessionKey) != mSessionCache.end());
- return SSLNoErr;
+ assert(lookupPriv(&sessionKey) != mSessionCache.end());
+ return noErr;
}
-SSLErr SessionCache::lookupEntry(
+OSStatus SessionCache::lookupEntry(
const SSLBuffer sessionKey,
SSLBuffer *sessionData)
{
SessionCacheIter existIter = lookupPriv(&sessionKey);
if(existIter == mSessionCache.end()) {
- return SSLSessionNotFoundErr;
+ return errSSLSessionNotFound;
}
SessionCacheEntry *entry = *existIter;
if(entry->isStale()) {
- cprintf(("SessionCache::lookupEntry %p: STALE entry, deleting\n", entry));
+ sslLogSessCacheDebug("SessionCache::lookupEntry %p: STALE "
+ "entry, deleting", entry);
cachePrint(&sessionKey, &entry->sessionData());
deletePriv(existIter);
- return SSLSessionNotFoundErr;
+ return errSSLSessionNotFound;
}
/* alloc/copy sessionData from existing entry (caller must free) */
- return SSLCopyBuffer(&entry->sessionData(), sessionData);
+ return SSLCopyBuffer(entry->sessionData(), *sessionData);
}
-SSLErr SessionCache::deleteEntry(
+OSStatus SessionCache::deleteEntry(
const SSLBuffer sessionKey)
{
StLock<Mutex> _(mSessionLock);
deletePriv(&sessionKey);
- return SSLNoErr;
+ return noErr;
}
/* cleanup, delete stale entries */
for(iter = mSessionCache.begin(); iter != mSessionCache.end(); ) {
SessionCacheEntry *entry = *iter;
if(entry->isStale(rightNow)) {
- #if CACHE_PRINT
- SSLBuffer *key = &entry->key();
- cprintf(("...SessionCache::cleanup: deleting cached session (%p)\n",
- entry));
- cachePrint(key, &entry->sessionData());
+ #ifndef DEBUG
+ sslLogSessCacheDebug("...SessionCache::cleanup: deleting "
+ "cached session (%p)", entry);
+ cachePrint(&entry->key(), &entry->sessionData());
#endif
iter = deletePriv(iter);
}
*/
#if CACHE_PRINT
SessionCacheEntry *entry = *iter;
- cprintf(("SessionCache::deletePriv %p\n", entry));
+ sslLogSessCacheDebug("SessionCache::deletePriv %p", entry);
cachePrint(sessionKey, &entry->sessionData());
dumpAllCache();
#endif
deletePriv(iter);
}
- CASSERT(lookupPriv(sessionKey) == mSessionCache.end());
+ assert(lookupPriv(sessionKey) == mSessionCache.end());
}
/* common erase, given a SessionCacheIter; returns next iter */
SessionCacheIter SessionCache::deletePriv(
SessionCacheIter iter)
{
- CASSERT(iter != mSessionCache.end());
+ assert(iter != mSessionCache.end());
SessionCacheEntry *entry = *iter;
SessionCacheIter nextIter = mSessionCache.erase(iter);
delete entry;
/*
* Store opaque sessionData, associated with opaque sessionKey.
*/
-SSLErr sslAddSession (
+OSStatus sslAddSession (
const SSLBuffer sessionKey,
const SSLBuffer sessionData)
{
- SSLErr serr;
+ OSStatus serr;
try {
serr = gSessionCache().addEntry(sessionKey, sessionData);
}
catch(...) {
- serr = SSLUnsupportedErr;
+ serr = unimpErr;
}
dumpAllCache();
return serr;
/*
* Given an opaque sessionKey, alloc & retrieve associated sessionData.
*/
-SSLErr sslGetSession (
+OSStatus sslGetSession (
const SSLBuffer sessionKey,
SSLBuffer *sessionData)
{
- SSLErr serr;
+ OSStatus serr;
try {
serr = gSessionCache().lookupEntry(sessionKey, sessionData);
}
catch(...) {
- serr = SSLSessionNotFoundErr;
+ serr = errSSLSessionNotFound;
}
- cprintf(("\nsslGetSession(%d, %p): %d\n", (int)sessionKey.length, sessionKey.data,
- serr));
- if(serr == SSLNoErr) {
+ sslLogSessCacheDebug("sslGetSession(%d, %p): %ld",
+ (int)sessionKey.length, sessionKey.data,
+ serr);
+ if(serr == noErr) {
cachePrint(&sessionKey, sessionData);
}
else {
return serr;
}
-SSLErr sslDeleteSession (
+OSStatus sslDeleteSession (
const SSLBuffer sessionKey)
{
- SSLErr serr;
+ OSStatus serr;
try {
serr = gSessionCache().deleteEntry(sessionKey);
}
catch(...) {
- serr = SSLSessionNotFoundErr;
+ serr = errSSLSessionNotFound;
}
return serr;
}
/* cleanup up session cache, deleting stale entries. */
-SSLErr sslCleanupSession ()
+OSStatus sslCleanupSession ()
{
- SSLErr serr = SSLNoErr;
+ OSStatus serr = noErr;
bool moreToGo = false;
try {
moreToGo = gSessionCache().cleanup();
}
catch(...) {
- serr = SSLSessionNotFoundErr;
+ serr = errSSLSessionNotFound;
}
/* Possible TBD: if moreToGo, schedule a timed callback to this function */
return serr;
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: cipherSpecs.c
-
- Contains: SSLCipherSpec declarations
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-#include "sslctx.h"
-#include "cryptType.h"
-#include "symCipher.h"
-#include "cipherSpecs.h"
-#include "sslDebug.h"
-#include "sslalloc.h"
-#include "sslDebug.h"
-#include "sslutil.h"
-#include <string.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
-/* FIXME - domestic suites do not work in server side in level 3 */
-
-#define ENABLE_3DES 1 /* normally enabled, our first preference */
-#define ENABLE_RC4 1 /* normally enabled, the most common one */
-#define ENABLE_DES 1 /* normally enabled */
-#define ENABLE_RC2 1 /* normally enabled */
-
-#define ENABLE_RSA_DES_SHA_NONEXPORT ENABLE_DES
-#define ENABLE_RSA_DES_MD5_NONEXPORT ENABLE_DES
-#define ENABLE_RSA_DES_SHA_EXPORT ENABLE_DES
-#define ENABLE_RSA_RC4_MD5_EXPORT ENABLE_RC4 /* the most common one */
-#define ENABLE_RSA_RC4_MD5_NONEXPORT ENABLE_RC4
-#define ENABLE_RSA_RC4_SHA_NONEXPORT ENABLE_RC4
-#define ENABLE_RSA_RC2_MD5_EXPORT ENABLE_RC2
-#define ENABLE_RSA_RC2_MD5_NONEXPORT ENABLE_RC2
-#define ENABLE_RSA_3DES_SHA ENABLE_3DES
-#define ENABLE_RSA_3DES_MD5 ENABLE_3DES
-
-extern SSLSymmetricCipher SSLCipherNull; /* in nullciph.c */
-
-/*
- * The symmetric ciphers currently supported (in addition to the
- * NULL cipher in nullciph.c).
- */
-#if ENABLE_DES
-static const SSLSymmetricCipher SSLCipherDES_CBC = {
- 8, /* Key size in bytes */
- 8, /* Secret key size = 64 bits */
- 8, /* IV size */
- 8, /* Block size */
- CSSM_ALGID_DES,
- CSSM_ALGID_DES,
- /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
- * for us */
- CSSM_ALGMODE_CBC_IV8,
- CSSM_PADDING_NONE,
- CDSASymmInit,
- CDSASymmEncrypt,
- CDSASymmDecrypt,
- CDSASymmFinish
-};
-
-static const SSLSymmetricCipher SSLCipherDES40_CBC = {
- 8, /* Key size in bytes */
- 5, /* Secret key size = 40 bits */
- 8, /* IV size */
- 8, /* Block size */
- CSSM_ALGID_DES,
- CSSM_ALGID_DES,
- CSSM_ALGMODE_CBC_IV8,
- CSSM_PADDING_NONE,
- CDSASymmInit,
- CDSASymmEncrypt,
- CDSASymmDecrypt,
- CDSASymmFinish
-};
-#endif /* ENABLE_DES */
-
-#if ENABLE_3DES
-static const SSLSymmetricCipher SSLCipher3DES_CBC = {
- 24, /* Key size in bytes */
- 24, /* Secret key size = 192 bits */
- 8, /* IV size */
- 8, /* Block size */
- CSSM_ALGID_3DES_3KEY, // key gen
- CSSM_ALGID_3DES_3KEY_EDE, // encryption
- /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
- * for us */
- CSSM_ALGMODE_CBC_IV8,
- CSSM_PADDING_NONE,
- CDSASymmInit,
- CDSASymmEncrypt,
- CDSASymmDecrypt,
- CDSASymmFinish
-};
-#endif /* ENABLE_3DES */
-
-#if ENABLE_RC4
-static const SSLSymmetricCipher SSLCipherRC4_40 = {
- 16, /* Key size in bytes */
- 5, /* Secret key size = 40 bits */
- 0, /* IV size */
- 0, /* Block size */
- CSSM_ALGID_RC4,
- CSSM_ALGID_RC4,
- CSSM_ALGMODE_NONE,
- CSSM_PADDING_NONE,
- CDSASymmInit,
- CDSASymmEncrypt,
- CDSASymmDecrypt,
- CDSASymmFinish
-};
-
-static const SSLSymmetricCipher SSLCipherRC4_128 = {
- 16, /* Key size in bytes */
- 16, /* Secret key size = 128 bits */
- 0, /* IV size */
- 0, /* Block size */
- CSSM_ALGID_RC4,
- CSSM_ALGID_RC4,
- CSSM_ALGMODE_NONE,
- CSSM_PADDING_NONE,
- CDSASymmInit,
- CDSASymmEncrypt,
- CDSASymmDecrypt,
- CDSASymmFinish
-};
-#endif /* ENABLE_RC4 */
-
-#if ENABLE_RC2
-static const SSLSymmetricCipher SSLCipherRC2_40 = {
- 16, /* Key size in bytes */
- 5, /* Secret key size = 40 bits */
- 8, /* IV size */
- 8, /* Block size */
- CSSM_ALGID_RC2,
- CSSM_ALGID_RC2,
- CSSM_ALGMODE_CBC_IV8,
- CSSM_PADDING_NONE,
- CDSASymmInit,
- CDSASymmEncrypt,
- CDSASymmDecrypt,
- CDSASymmFinish
-};
-
-static const SSLSymmetricCipher SSLCipherRC2_128 = {
- 16, /* Key size in bytes */
- 16, /* Secret key size = 40 bits */
- 8, /* IV size */
- 8, /* Block size */
- CSSM_ALGID_RC2,
- CSSM_ALGID_RC2,
- CSSM_ALGMODE_CBC_IV8,
- CSSM_PADDING_NONE,
- CDSASymmInit,
- CDSASymmEncrypt,
- CDSASymmDecrypt,
- CDSASymmFinish
-};
-
-#endif /* ENABLE_RC2*/
-
-
-/* Even if we don't support NULL_WITH_NULL_NULL for transport,
- * we need a reference for startup */
-const SSLCipherSpec SSL_NULL_WITH_NULL_NULL_CipherSpec =
-{ SSL_NULL_WITH_NULL_NULL,
- Exportable,
- SSL_NULL_auth,
- &HashHmacNull,
- &SSLCipherNull
-};
-
-/*
- * List of all CipherSpecs we implement. Depending on a context's
- * exportable flag, not all of these might be available for use.
- *
- * FIXME - I'm not sure the distinction between e.g. SSL_RSA and SSL_RSA_EXPORT
- * makes any sense here. See comments for the definition of
- * KeyExchangeMethod in cryptType.h.
- */
-/* Order by preference, domestic first */
-static const SSLCipherSpec KnownCipherSpecs[] =
-{
- /*** domestic only ***/
- #if ENABLE_RSA_3DES_SHA
- {
- SSL_RSA_WITH_3DES_EDE_CBC_SHA,
- NotExportable,
- SSL_RSA,
- &HashHmacSHA1,
- &SSLCipher3DES_CBC
- },
- #endif
- #if ENABLE_RSA_3DES_MD5
- {
- SSL_RSA_WITH_3DES_EDE_CBC_MD5,
- NotExportable,
- SSL_RSA,
- &HashHmacMD5,
- &SSLCipher3DES_CBC
- },
- #endif
- #if ENABLE_RSA_RC4_SHA_NONEXPORT
- {
- SSL_RSA_WITH_RC4_128_SHA,
- NotExportable,
- SSL_RSA,
- &HashHmacSHA1,
- &SSLCipherRC4_128
- },
- #endif
- #if ENABLE_RSA_RC4_MD5_NONEXPORT
- {
- SSL_RSA_WITH_RC4_128_MD5,
- NotExportable,
- SSL_RSA,
- &HashHmacMD5,
- &SSLCipherRC4_128
- },
- #endif
- #if ENABLE_RSA_DES_SHA_NONEXPORT
- {
- SSL_RSA_WITH_DES_CBC_SHA,
- NotExportable,
- SSL_RSA,
- &HashHmacSHA1,
- &SSLCipherDES_CBC
- },
- #endif
- #if ENABLE_RSA_DES_MD5_NONEXPORT
- {
- SSL_RSA_WITH_DES_CBC_MD5,
- NotExportable,
- SSL_RSA,
- &HashHmacMD5,
- &SSLCipherDES_CBC
- },
- #endif
- /*** exportable ***/
- #if ENABLE_RSA_RC4_MD5_EXPORT
- {
- SSL_RSA_EXPORT_WITH_RC4_40_MD5,
- Exportable,
- SSL_RSA_EXPORT,
- &HashHmacMD5,
- &SSLCipherRC4_40
- },
- #endif
- #if APPLE_DH
- /* Apple CSP doesn't support D-H yet */
- {
- SSL_DH_anon_WITH_RC4_128_MD5,
- NotExportable,
- SSL_DH_anon,
- &HashHmacMD5,
- &SSLCipherRC4_128
- },
- #endif
- #if ENABLE_RSA_DES_SHA_EXPORT
- {
- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
- Exportable,
- SSL_RSA_EXPORT,
- &HashHmacSHA1,
- &SSLCipherDES40_CBC
- },
- #endif
-
- #if ENABLE_RSA_RC2_MD5_EXPORT
- {
- SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- Exportable,
- SSL_RSA_EXPORT,
- &HashHmacMD5,
- &SSLCipherRC2_40
- },
- #endif
- #if ENABLE_RSA_RC2_MD5_NONEXPORT
- {
- SSL_RSA_WITH_RC2_CBC_MD5,
- NotExportable,
- SSL_RSA,
- &HashHmacMD5,
- &SSLCipherRC2_128
- },
- #endif
- {
- SSL_RSA_WITH_NULL_MD5,
- Exportable,
- SSL_RSA,
- &HashHmacMD5,
- &SSLCipherNull
- }
-};
-
-static const int CipherSpecCount = sizeof(KnownCipherSpecs) / sizeof(SSLCipherSpec);
-
-/*
- * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
- * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
- * not been called).
- */
-SSLErr sslBuildCipherSpecArray(SSLContext *ctx)
-{
- unsigned size;
-
- CASSERT(ctx != NULL);
- CASSERT(ctx->validCipherSpecs == NULL);
-
- ctx->numValidCipherSpecs = CipherSpecCount;
- size = CipherSpecCount * sizeof(SSLCipherSpec);
- ctx->validCipherSpecs = sslMalloc(size);
- if(ctx->validCipherSpecs == NULL) {
- ctx->numValidCipherSpecs = 0;
- return SSLMemoryErr;
- }
- memmove(ctx->validCipherSpecs, KnownCipherSpecs, size);
- return SSLNoErr;
-}
-
-/*
- * Convert an array of SSLCipherSpecs (which is either KnownCipherSpecs or
- * ctx->validCipherSpecs) to an array of SSLCipherSuites.
- */
-static OSStatus
-cipherSpecsToCipherSuites(
- UInt32 numCipherSpecs, /* size of cipherSpecs */
- const SSLCipherSpec *cipherSpecs,
- SSLCipherSuite *ciphers, /* RETURNED */
- UInt32 *numCiphers) /* IN/OUT */
-{
- unsigned dex;
-
- if(*numCiphers < numCipherSpecs) {
- return errSSLBufferOverflow;
- }
- for(dex=0; dex<numCipherSpecs; dex++) {
- ciphers[dex] = cipherSpecs[dex].cipherSpec;
- }
- *numCiphers = numCipherSpecs;
- return noErr;
-}
-
-/***
- *** Publically exported functions declared in SecureTransport.h
- ***/
-
-/*
- * Determine number and values of all of the SSLCipherSuites we support.
- * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
- * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
- * will be returned.
- */
-OSStatus
-SSLGetNumberSupportedCiphers (SSLContextRef ctx,
- UInt32 *numCiphers)
-{
- if((ctx == NULL) || (numCiphers == NULL)) {
- return paramErr;
- }
- *numCiphers = CipherSpecCount;
- return noErr;
-}
-
-OSStatus
-SSLGetSupportedCiphers (SSLContextRef ctx,
- SSLCipherSuite *ciphers, /* RETURNED */
- UInt32 *numCiphers) /* IN/OUT */
-{
- if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
- return paramErr;
- }
- return cipherSpecsToCipherSuites(CipherSpecCount,
- KnownCipherSpecs,
- ciphers,
- numCiphers);
-}
-
-/*
- * Specify a (typically) restricted set of SSLCipherSuites to be enabled by
- * the current SSLContext. Can only be called when no session is active. Default
- * set of enabled SSLCipherSuites is the same as the complete set of supported
- * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
- */
-OSStatus
-SSLSetEnabledCiphers (SSLContextRef ctx,
- const SSLCipherSuite *ciphers,
- UInt32 numCiphers)
-{
- unsigned size;
- unsigned callerDex;
- unsigned tableDex;
-
- if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- size = numCiphers * sizeof(SSLCipherSpec);
- ctx->validCipherSpecs = sslMalloc(size);
- if(ctx->validCipherSpecs == NULL) {
- ctx->numValidCipherSpecs = 0;
- return SSLMemoryErr;
- }
-
- /*
- * Run thru caller's specs, finding a matching SSLCipherSpec for each one.
- * If caller specifies one we don't know about, abort.
- */
- for(callerDex=0; callerDex<numCiphers; callerDex++) {
- /* find matching CipherSpec in our known table */
- int foundOne = 0;
- for(tableDex=0; tableDex<CipherSpecCount; tableDex++) {
- if(ciphers[callerDex] == KnownCipherSpecs[tableDex].cipherSpec) {
- ctx->validCipherSpecs[callerDex] = KnownCipherSpecs[tableDex];
- foundOne = 1;
- break;
- }
- }
- if(!foundOne) {
- /* caller specified one we don't implement */
- sslFree(ctx->validCipherSpecs);
- ctx->validCipherSpecs = NULL;
- return errSSLBadCipherSuite;
- }
- }
-
- /* success */
- ctx->numValidCipherSpecs = numCiphers;
- return noErr;
-}
-
-/*
- * Determine number and values of all of the SSLCipherSuites currently enabled.
- * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
- * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
- * will be returned.
- */
-OSStatus
-SSLGetNumberEnabledCiphers (SSLContextRef ctx,
- UInt32 *numCiphers)
-{
- if((ctx == NULL) || (numCiphers == NULL)) {
- return paramErr;
- }
- if(ctx->validCipherSpecs == NULL) {
- /* hasn't been set; use default */
- *numCiphers = CipherSpecCount;
- }
- else {
- /* caller set via SSLSetEnabledCiphers */
- *numCiphers = ctx->numValidCipherSpecs;
- }
- return noErr;
-}
-
-OSStatus
-SSLGetEnabledCiphers (SSLContextRef ctx,
- SSLCipherSuite *ciphers, /* RETURNED */
- UInt32 *numCiphers) /* IN/OUT */
-{
- if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
- return paramErr;
- }
- if(ctx->validCipherSpecs == NULL) {
- /* hasn't been set; use default */
- return cipherSpecsToCipherSuites(CipherSpecCount,
- KnownCipherSpecs,
- ciphers,
- numCiphers);
- }
- else {
- /* use the ones specified in SSLSetEnabledCiphers() */
- return cipherSpecsToCipherSuites(ctx->numValidCipherSpecs,
- ctx->validCipherSpecs,
- ciphers,
- numCiphers);
- }
-}
-
-/***
- *** End of publically exported functions declared in SecureTransport.h
- ***/
-
-/*
- * Given a valid ctx->selectedCipher and ctx->validCipherSpecs, set
- * ctx->selectedCipherSpec as appropriate.
- */
-SSLErr
-FindCipherSpec(SSLContext *ctx)
-{
-
- unsigned i;
-
- CASSERT(ctx != NULL);
- CASSERT(ctx->validCipherSpecs != NULL);
-
- ctx->selectedCipherSpec = NULL;
- for (i=0; i<ctx->numValidCipherSpecs; i++)
- { if (ctx->validCipherSpecs[i].cipherSpec == ctx->selectedCipher) {
- ctx->selectedCipherSpec = &ctx->validCipherSpecs[i];
- break;
- }
- }
- if (ctx->selectedCipherSpec == NULL) /* Not found */
- return SSLNegotiationErr;
- return SSLNoErr;
-}
-
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: cipherSpecs.cpp
+
+ Contains: SSLCipherSpec declarations
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "cryptType.h"
+#include "symCipher.h"
+#include "cipherSpecs.h"
+#include "sslDebug.h"
+#include "sslMemory.h"
+#include "sslDebug.h"
+#include "sslUtils.h"
+#include <string.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#define ENABLE_3DES 1 /* normally enabled, our first preference */
+#define ENABLE_RC4 1 /* normally enabled, the most common one */
+#define ENABLE_DES 1 /* normally enabled */
+#define ENABLE_RC2 1 /* normally enabled */
+
+#define ENABLE_RSA_DES_SHA_NONEXPORT ENABLE_DES
+#define ENABLE_RSA_DES_MD5_NONEXPORT ENABLE_DES
+#define ENABLE_RSA_DES_SHA_EXPORT ENABLE_DES
+#define ENABLE_RSA_RC4_MD5_EXPORT ENABLE_RC4 /* the most common one */
+#define ENABLE_RSA_RC4_MD5_NONEXPORT ENABLE_RC4
+#define ENABLE_RSA_RC4_SHA_NONEXPORT ENABLE_RC4
+#define ENABLE_RSA_RC2_MD5_EXPORT ENABLE_RC2
+#define ENABLE_RSA_RC2_MD5_NONEXPORT ENABLE_RC2
+#define ENABLE_RSA_3DES_SHA ENABLE_3DES
+#define ENABLE_RSA_3DES_MD5 ENABLE_3DES
+
+extern "C" {
+extern const SSLSymmetricCipher SSLCipherNull; /* in sslNullCipher.cpp */
+}
+
+/*
+ * The symmetric ciphers currently supported (in addition to the
+ * NULL cipher in nullciph.c).
+ */
+#if ENABLE_DES
+static const SSLSymmetricCipher SSLCipherDES_CBC = {
+ 8, /* Key size in bytes */
+ 8, /* Secret key size = 64 bits */
+ 8, /* IV size */
+ 8, /* Block size */
+ CSSM_ALGID_DES,
+ CSSM_ALGID_DES,
+ /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
+ * for us */
+ CSSM_ALGMODE_CBC_IV8,
+ CSSM_PADDING_NONE,
+ CDSASymmInit,
+ CDSASymmEncrypt,
+ CDSASymmDecrypt,
+ CDSASymmFinish
+};
+
+static const SSLSymmetricCipher SSLCipherDES40_CBC = {
+ 8, /* Key size in bytes */
+ 5, /* Secret key size = 40 bits */
+ 8, /* IV size */
+ 8, /* Block size */
+ CSSM_ALGID_DES,
+ CSSM_ALGID_DES,
+ CSSM_ALGMODE_CBC_IV8,
+ CSSM_PADDING_NONE,
+ CDSASymmInit,
+ CDSASymmEncrypt,
+ CDSASymmDecrypt,
+ CDSASymmFinish
+};
+#endif /* ENABLE_DES */
+
+#if ENABLE_3DES
+static const SSLSymmetricCipher SSLCipher3DES_CBC = {
+ 24, /* Key size in bytes */
+ 24, /* Secret key size = 192 bits */
+ 8, /* IV size */
+ 8, /* Block size */
+ CSSM_ALGID_3DES_3KEY, // key gen
+ CSSM_ALGID_3DES_3KEY_EDE, // encryption
+ /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
+ * for us */
+ CSSM_ALGMODE_CBC_IV8,
+ CSSM_PADDING_NONE,
+ CDSASymmInit,
+ CDSASymmEncrypt,
+ CDSASymmDecrypt,
+ CDSASymmFinish
+};
+#endif /* ENABLE_3DES */
+
+#if ENABLE_RC4
+static const SSLSymmetricCipher SSLCipherRC4_40 = {
+ 16, /* Key size in bytes */
+ 5, /* Secret key size = 40 bits */
+ 0, /* IV size */
+ 0, /* Block size */
+ CSSM_ALGID_RC4,
+ CSSM_ALGID_RC4,
+ CSSM_ALGMODE_NONE,
+ CSSM_PADDING_NONE,
+ CDSASymmInit,
+ CDSASymmEncrypt,
+ CDSASymmDecrypt,
+ CDSASymmFinish
+};
+
+static const SSLSymmetricCipher SSLCipherRC4_128 = {
+ 16, /* Key size in bytes */
+ 16, /* Secret key size = 128 bits */
+ 0, /* IV size */
+ 0, /* Block size */
+ CSSM_ALGID_RC4,
+ CSSM_ALGID_RC4,
+ CSSM_ALGMODE_NONE,
+ CSSM_PADDING_NONE,
+ CDSASymmInit,
+ CDSASymmEncrypt,
+ CDSASymmDecrypt,
+ CDSASymmFinish
+};
+#endif /* ENABLE_RC4 */
+
+#if ENABLE_RC2
+static const SSLSymmetricCipher SSLCipherRC2_40 = {
+ 16, /* Key size in bytes */
+ 5, /* Secret key size = 40 bits */
+ 8, /* IV size */
+ 8, /* Block size */
+ CSSM_ALGID_RC2,
+ CSSM_ALGID_RC2,
+ CSSM_ALGMODE_CBC_IV8,
+ CSSM_PADDING_NONE,
+ CDSASymmInit,
+ CDSASymmEncrypt,
+ CDSASymmDecrypt,
+ CDSASymmFinish
+};
+
+static const SSLSymmetricCipher SSLCipherRC2_128 = {
+ 16, /* Key size in bytes */
+ 16, /* Secret key size = 40 bits */
+ 8, /* IV size */
+ 8, /* Block size */
+ CSSM_ALGID_RC2,
+ CSSM_ALGID_RC2,
+ CSSM_ALGMODE_CBC_IV8,
+ CSSM_PADDING_NONE,
+ CDSASymmInit,
+ CDSASymmEncrypt,
+ CDSASymmDecrypt,
+ CDSASymmFinish
+};
+
+#endif /* ENABLE_RC2*/
+
+
+/* Even if we don't support NULL_WITH_NULL_NULL for transport,
+ * we need a reference for startup */
+const SSLCipherSpec SSL_NULL_WITH_NULL_NULL_CipherSpec =
+{ SSL_NULL_WITH_NULL_NULL,
+ Exportable,
+ SSL_NULL_auth,
+ &HashHmacNull,
+ &SSLCipherNull
+};
+
+/*
+ * List of all CipherSpecs we implement. Depending on a context's
+ * exportable flag, not all of these might be available for use.
+ *
+ * FIXME - I'm not sure the distinction between e.g. SSL_RSA and SSL_RSA_EXPORT
+ * makes any sense here. See comments for the definition of
+ * KeyExchangeMethod in cryptType.h.
+ */
+/* Order by preference, domestic first */
+static const SSLCipherSpec KnownCipherSpecs[] =
+{
+ /*** domestic only ***/
+ #if ENABLE_RSA_3DES_SHA
+ {
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+ NotExportable,
+ SSL_RSA,
+ &HashHmacSHA1,
+ &SSLCipher3DES_CBC
+ },
+ #endif
+ #if ENABLE_RSA_3DES_MD5
+ {
+ SSL_RSA_WITH_3DES_EDE_CBC_MD5,
+ NotExportable,
+ SSL_RSA,
+ &HashHmacMD5,
+ &SSLCipher3DES_CBC
+ },
+ #endif
+ #if ENABLE_RSA_RC4_SHA_NONEXPORT
+ {
+ SSL_RSA_WITH_RC4_128_SHA,
+ NotExportable,
+ SSL_RSA,
+ &HashHmacSHA1,
+ &SSLCipherRC4_128
+ },
+ #endif
+ #if ENABLE_RSA_RC4_MD5_NONEXPORT
+ {
+ SSL_RSA_WITH_RC4_128_MD5,
+ NotExportable,
+ SSL_RSA,
+ &HashHmacMD5,
+ &SSLCipherRC4_128
+ },
+ #endif
+ #if ENABLE_RSA_DES_SHA_NONEXPORT
+ {
+ SSL_RSA_WITH_DES_CBC_SHA,
+ NotExportable,
+ SSL_RSA,
+ &HashHmacSHA1,
+ &SSLCipherDES_CBC
+ },
+ #endif
+ #if ENABLE_RSA_DES_MD5_NONEXPORT
+ {
+ SSL_RSA_WITH_DES_CBC_MD5,
+ NotExportable,
+ SSL_RSA,
+ &HashHmacMD5,
+ &SSLCipherDES_CBC
+ },
+ #endif
+ /*** exportable ***/
+ #if ENABLE_RSA_RC4_MD5_EXPORT
+ {
+ SSL_RSA_EXPORT_WITH_RC4_40_MD5,
+ Exportable,
+ SSL_RSA_EXPORT,
+ &HashHmacMD5,
+ &SSLCipherRC4_40
+ },
+ #endif
+ #if APPLE_DH
+ /* Apple CSP doesn't support D-H yet */
+ {
+ SSL_DH_anon_WITH_RC4_128_MD5,
+ NotExportable,
+ SSL_DH_anon,
+ &HashHmacMD5,
+ &SSLCipherRC4_128
+ },
+ #endif
+ #if ENABLE_RSA_DES_SHA_EXPORT
+ {
+ SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ Exportable,
+ SSL_RSA_EXPORT,
+ &HashHmacSHA1,
+ &SSLCipherDES40_CBC
+ },
+ #endif
+
+ #if ENABLE_RSA_RC2_MD5_EXPORT
+ {
+ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+ Exportable,
+ SSL_RSA_EXPORT,
+ &HashHmacMD5,
+ &SSLCipherRC2_40
+ },
+ #endif
+ #if ENABLE_RSA_RC2_MD5_NONEXPORT
+ {
+ SSL_RSA_WITH_RC2_CBC_MD5,
+ NotExportable,
+ SSL_RSA,
+ &HashHmacMD5,
+ &SSLCipherRC2_128
+ },
+ #endif
+ {
+ SSL_RSA_WITH_NULL_MD5,
+ Exportable,
+ SSL_RSA,
+ &HashHmacMD5,
+ &SSLCipherNull
+ }
+};
+
+static const unsigned CipherSpecCount = sizeof(KnownCipherSpecs) / sizeof(SSLCipherSpec);
+
+/*
+ * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
+ * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
+ * not been called).
+ */
+OSStatus sslBuildCipherSpecArray(SSLContext *ctx)
+{
+ unsigned size;
+
+ assert(ctx != NULL);
+ assert(ctx->validCipherSpecs == NULL);
+
+ ctx->numValidCipherSpecs = CipherSpecCount;
+ size = CipherSpecCount * sizeof(SSLCipherSpec);
+ ctx->validCipherSpecs = (SSLCipherSpec *)sslMalloc(size);
+ if(ctx->validCipherSpecs == NULL) {
+ ctx->numValidCipherSpecs = 0;
+ return memFullErr;
+ }
+ memmove(ctx->validCipherSpecs, KnownCipherSpecs, size);
+ return noErr;
+}
+
+/*
+ * Convert an array of SSLCipherSpecs (which is either KnownCipherSpecs or
+ * ctx->validCipherSpecs) to an array of SSLCipherSuites.
+ */
+static OSStatus
+cipherSpecsToCipherSuites(
+ UInt32 numCipherSpecs, /* size of cipherSpecs */
+ const SSLCipherSpec *cipherSpecs,
+ SSLCipherSuite *ciphers, /* RETURNED */
+ UInt32 *numCiphers) /* IN/OUT */
+{
+ unsigned dex;
+
+ if(*numCiphers < numCipherSpecs) {
+ return errSSLBufferOverflow;
+ }
+ for(dex=0; dex<numCipherSpecs; dex++) {
+ ciphers[dex] = cipherSpecs[dex].cipherSpec;
+ }
+ *numCiphers = numCipherSpecs;
+ return noErr;
+}
+
+/***
+ *** Publically exported functions declared in SecureTransport.h
+ ***/
+
+/*
+ * Determine number and values of all of the SSLCipherSuites we support.
+ * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
+ * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
+ * will be returned.
+ */
+OSStatus
+SSLGetNumberSupportedCiphers (SSLContextRef ctx,
+ UInt32 *numCiphers)
+{
+ if((ctx == NULL) || (numCiphers == NULL)) {
+ return paramErr;
+ }
+ *numCiphers = CipherSpecCount;
+ return noErr;
+}
+
+OSStatus
+SSLGetSupportedCiphers (SSLContextRef ctx,
+ SSLCipherSuite *ciphers, /* RETURNED */
+ UInt32 *numCiphers) /* IN/OUT */
+{
+ if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
+ return paramErr;
+ }
+ return cipherSpecsToCipherSuites(CipherSpecCount,
+ KnownCipherSpecs,
+ ciphers,
+ numCiphers);
+}
+
+/*
+ * Specify a (typically) restricted set of SSLCipherSuites to be enabled by
+ * the current SSLContext. Can only be called when no session is active. Default
+ * set of enabled SSLCipherSuites is the same as the complete set of supported
+ * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
+ */
+OSStatus
+SSLSetEnabledCiphers (SSLContextRef ctx,
+ const SSLCipherSuite *ciphers,
+ UInt32 numCiphers)
+{
+ unsigned size;
+ unsigned callerDex;
+ unsigned tableDex;
+
+ if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ size = numCiphers * sizeof(SSLCipherSpec);
+ ctx->validCipherSpecs = (SSLCipherSpec *)sslMalloc(size);
+ if(ctx->validCipherSpecs == NULL) {
+ ctx->numValidCipherSpecs = 0;
+ return memFullErr;
+ }
+
+ /*
+ * Run thru caller's specs, finding a matching SSLCipherSpec for each one.
+ * If caller specifies one we don't know about, abort.
+ */
+ for(callerDex=0; callerDex<numCiphers; callerDex++) {
+ /* find matching CipherSpec in our known table */
+ int foundOne = 0;
+ for(tableDex=0; tableDex<CipherSpecCount; tableDex++) {
+ if(ciphers[callerDex] == KnownCipherSpecs[tableDex].cipherSpec) {
+ ctx->validCipherSpecs[callerDex] = KnownCipherSpecs[tableDex];
+ foundOne = 1;
+ break;
+ }
+ }
+ if(!foundOne) {
+ /* caller specified one we don't implement */
+ sslFree(ctx->validCipherSpecs);
+ ctx->validCipherSpecs = NULL;
+ return errSSLBadCipherSuite;
+ }
+ }
+
+ /* success */
+ ctx->numValidCipherSpecs = numCiphers;
+ return noErr;
+}
+
+/*
+ * Determine number and values of all of the SSLCipherSuites currently enabled.
+ * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
+ * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
+ * will be returned.
+ */
+OSStatus
+SSLGetNumberEnabledCiphers (SSLContextRef ctx,
+ UInt32 *numCiphers)
+{
+ if((ctx == NULL) || (numCiphers == NULL)) {
+ return paramErr;
+ }
+ if(ctx->validCipherSpecs == NULL) {
+ /* hasn't been set; use default */
+ *numCiphers = CipherSpecCount;
+ }
+ else {
+ /* caller set via SSLSetEnabledCiphers */
+ *numCiphers = ctx->numValidCipherSpecs;
+ }
+ return noErr;
+}
+
+OSStatus
+SSLGetEnabledCiphers (SSLContextRef ctx,
+ SSLCipherSuite *ciphers, /* RETURNED */
+ UInt32 *numCiphers) /* IN/OUT */
+{
+ if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
+ return paramErr;
+ }
+ if(ctx->validCipherSpecs == NULL) {
+ /* hasn't been set; use default */
+ return cipherSpecsToCipherSuites(CipherSpecCount,
+ KnownCipherSpecs,
+ ciphers,
+ numCiphers);
+ }
+ else {
+ /* use the ones specified in SSLSetEnabledCiphers() */
+ return cipherSpecsToCipherSuites(ctx->numValidCipherSpecs,
+ ctx->validCipherSpecs,
+ ciphers,
+ numCiphers);
+ }
+}
+
+/***
+ *** End of publically exported functions declared in SecureTransport.h
+ ***/
+
+/*
+ * Given a valid ctx->selectedCipher and ctx->validCipherSpecs, set
+ * ctx->selectedCipherSpec as appropriate.
+ */
+OSStatus
+FindCipherSpec(SSLContext *ctx)
+{
+
+ unsigned i;
+
+ assert(ctx != NULL);
+ assert(ctx->validCipherSpecs != NULL);
+
+ ctx->selectedCipherSpec = NULL;
+ for (i=0; i<ctx->numValidCipherSpecs; i++)
+ { if (ctx->validCipherSpecs[i].cipherSpec == ctx->selectedCipher) {
+ ctx->selectedCipherSpec = &ctx->validCipherSpecs[i];
+ break;
+ }
+ }
+ if (ctx->selectedCipherSpec == NULL) /* Not found */
+ return errSSLNegotiation;
+ return noErr;
+}
+
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-#include "sslBuildFlags.h"
-#include <Security/cssmtype.h>
-#include "appleCdsa.h"
-#include <Security/cssmerrno.h>
-
-#if SSL_DEBUG
-void stPrintCdsaError(const char *op, CSSM_RETURN crtn)
-{
- cssmPerror(op, crtn);
-}
-
-char *stCssmErrToStr(CSSM_RETURN err)
-{
- string errStr = cssmErrorString(err);
- return const_cast<char *>(errStr.c_str());
-}
-#endif
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: digests.c
-
- Contains: interface between SSL and SHA, MD5 digest libraries
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: digests.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: digests.c Hashing support functions and data structures
-
- Contains interface functions which generalize hashing support for MD5
- and SHA1 and a dummy null hash implementation (used before MACing is
- turned on). Also, utility functions for using the hashes.
-
- ****************************************************************** */
-
-#include "sslctx.h"
-#include "cryptType.h"
-#include "sslalloc.h"
-#include "digests.h"
-#include "sslDebug.h"
-#include "appleCdsa.h"
-#include <Security/cssm.h>
-#include <string.h>
-
-#define DIGEST_PRINT 0
-#if DIGEST_PRINT
-#define dgprintf(s) printf s
-#else
-#define dgprintf(s)
-#endif
-
-/*
- * Common digest context. The SSLBuffer.data pointer in a "digest state" argument
- * casts to one of these.
- */
-typedef struct {
- CSSM_CC_HANDLE hashHand;
-} cdsaHashContext;
-
-uint8 SSLMACPad1[MAX_MAC_PADDING], SSLMACPad2[MAX_MAC_PADDING];
-
-/*
- * Public general hash functions
- */
-void
-SSLInitMACPads(void)
-{ int i;
-
- for (i = 0; i < MAX_MAC_PADDING; i++)
- { SSLMACPad1[i] = 0x36;
- SSLMACPad2[i] = 0x5C;
- }
-}
-
-/*
- * A convenience wrapper for HashReference.clone, which has the added benefit of
- * allocating the state buffer for the caller.
- */
-SSLErr
-CloneHashState(const HashReference *ref, SSLBuffer state, SSLBuffer *newState, SSLContext *ctx)
-{
- SSLErr err;
- if ((err = SSLAllocBuffer(newState, ref->contextSize, &ctx->sysCtx)) != 0)
- return err;
- return ref->clone(state, *newState);
-}
-
-/*
- * Wrapper for HashReference.init.
- */
-SSLErr
-ReadyHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
-{
- SSLErr err;
- if ((err = SSLAllocBuffer(state, ref->contextSize, &ctx->sysCtx)) != 0)
- return err;
- return ref->init(*state, ctx);
-}
-
-/*
- * Wrapper for HashReference.clone. Tolerates NULL digestCtx and frees it if it's
- * there.
- */
-SSLErr CloseHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
-{
- SSLErr serr;
-
- if((state == NULL) || (state->data == NULL)) {
- return SSLNoErr;
- }
- serr = ref->close(*state, ctx);
- if(serr) {
- return serr;
- }
- return SSLFreeBuffer(state, &ctx->sysCtx);
-}
-
-static SSLErr HashNullInit(SSLBuffer digestCtx, SSLContext *sslCtx);
-static SSLErr HashNullUpdate(SSLBuffer,SSLBuffer);
-static SSLErr HashNullFinal(SSLBuffer,SSLBuffer);
-static SSLErr HashNullClose(SSLBuffer digestCtx, SSLContext *sslCtx);
-static SSLErr HashNullClone(SSLBuffer,SSLBuffer);
-
-static SSLErr HashMD5Init(SSLBuffer digestCtx, SSLContext *sslCtx);
-static SSLErr HashSHA1Init(SSLBuffer digestCtx, SSLContext *sslCtx);
-static SSLErr cdsaHashInit(SSLBuffer digestCtx, SSLContext *sslCtx,
- CSSM_ALGORITHMS digestAlg);
-static SSLErr cdsaHashUpdate(SSLBuffer digestCtx, SSLBuffer data);
-static SSLErr cdsaHashFinal(SSLBuffer digestCtx, SSLBuffer digest);
-static SSLErr cdsaHashClose(SSLBuffer digestCtx, SSLContext *sslCtx);
-static SSLErr cdsaHashClone(SSLBuffer src, SSLBuffer dest);
-
-/*
- * These are the handles by which the bulk of digesting work
- * is done.
- */
-const HashReference SSLHashNull =
- {
- 0,
- 0,
- 0,
- HashNullInit,
- HashNullUpdate,
- HashNullFinal,
- HashNullClose,
- HashNullClone
- };
-
-const HashReference SSLHashMD5 =
- {
- sizeof(cdsaHashContext),
- 16,
- 48,
- HashMD5Init,
- cdsaHashUpdate,
- cdsaHashFinal,
- cdsaHashClose,
- cdsaHashClone
- };
-
-const HashReference SSLHashSHA1 =
- {
- sizeof(cdsaHashContext),
- 20,
- 40,
- HashSHA1Init,
- cdsaHashUpdate,
- cdsaHashFinal,
- cdsaHashClose,
- cdsaHashClone
- };
-
-/*** NULL ***/
-static SSLErr HashNullInit(SSLBuffer digestCtx, SSLContext *sslCtx) {
- return SSLNoErr;
-}
-
-static SSLErr HashNullUpdate(SSLBuffer digestCtx, SSLBuffer data) {
- return SSLNoErr;
-}
-
-static SSLErr HashNullFinal(SSLBuffer digestCtx, SSLBuffer digest) {
- return SSLNoErr;
-}
-static SSLErr HashNullClose(SSLBuffer digestCtx, SSLContext *sslCtx) {
- return SSLNoErr;
-}
-static SSLErr HashNullClone(SSLBuffer src, SSLBuffer dest) {
- return SSLNoErr;
-}
-
-static SSLErr HashMD5Init(SSLBuffer digestCtx, SSLContext *sslCtx)
-{
- CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
- return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_MD5);
-}
-
-static SSLErr HashSHA1Init(SSLBuffer digestCtx, SSLContext *sslCtx)
-{
- CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
- return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_SHA1);
-}
-
-/* common digest functions via CDSA */
-static SSLErr cdsaHashInit(SSLBuffer digestCtx,
- SSLContext *sslCtx,
- CSSM_ALGORITHMS digestAlg)
-{
- SSLErr serr;
- cdsaHashContext *cdsaCtx;
- CSSM_CC_HANDLE hashHand = 0;
- CSSM_RETURN crtn;
-
- CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
- serr = attachToCsp(sslCtx); // should be a nop
- if(serr) {
- return serr;
- }
- cdsaCtx = (cdsaHashContext *)digestCtx.data;
- cdsaCtx->hashHand = 0;
- dgprintf(("###cdsaHashInit cdsaCtx %p\n", cdsaCtx));
-
- /* cook up a digest context, initialize it */
- crtn = CSSM_CSP_CreateDigestContext(sslCtx->cspHand,
- digestAlg,
- &hashHand);
- if(crtn) {
- errorLog0("CSSM_CSP_CreateDigestContext failure\n");
- return SSLCryptoError;
- }
- crtn = CSSM_DigestDataInit(hashHand);
- if(crtn) {
- CSSM_DeleteContext(hashHand);
- errorLog0("CSSM_DigestDataInit failure\n");
- return SSLCryptoError;
- }
- cdsaCtx->hashHand = hashHand;
- return SSLNoErr;
-}
-
-static SSLErr cdsaHashUpdate(SSLBuffer digestCtx, SSLBuffer data)
-{
- cdsaHashContext *cdsaCtx;
- CSSM_RETURN crtn;
- CSSM_DATA cdata;
-
- CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
- cdsaCtx = (cdsaHashContext *)digestCtx.data;
- //dgprintf(("###cdsaHashUpdate cdsaCtx %p\n", cdsaCtx));
-
- SSLBUF_TO_CSSM(&data, &cdata);
- crtn = CSSM_DigestDataUpdate(cdsaCtx->hashHand, &cdata, 1);
- if(crtn) {
- errorLog0("CSSM_DigestDataUpdate failure\n");
- return SSLCryptoError;
- }
- else {
- return SSLNoErr;
- }
-}
-
-static SSLErr cdsaHashFinal(SSLBuffer digestCtx, SSLBuffer digest)
-{
- cdsaHashContext *cdsaCtx;
- CSSM_RETURN crtn;
- CSSM_DATA cdata;
- SSLErr srtn = SSLNoErr;
-
- CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
- cdsaCtx = (cdsaHashContext *)digestCtx.data;
- dgprintf(("###cdsaHashFinal cdsaCtx %p\n", cdsaCtx));
- SSLBUF_TO_CSSM(&digest, &cdata);
- crtn = CSSM_DigestDataFinal(cdsaCtx->hashHand, &cdata);
- if(crtn) {
- errorLog0("CSSM_DigestDataFinal failure\n");
- srtn = SSLCryptoError;
- }
- else {
- digest.length = cdata.Length;
- }
- CSSM_DeleteContext(cdsaCtx->hashHand);
- cdsaCtx->hashHand = 0;
- return srtn;
-}
-
-static SSLErr cdsaHashClose(SSLBuffer digestCtx, SSLContext *sslCtx)
-{
- cdsaHashContext *cdsaCtx;
-
- CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
- cdsaCtx = (cdsaHashContext *)digestCtx.data;
- dgprintf(("###cdsaHashClose cdsaCtx %p\n", cdsaCtx));
- if(cdsaCtx->hashHand != 0) {
- CSSM_DeleteContext(cdsaCtx->hashHand);
- cdsaCtx->hashHand = 0;
- }
- return SSLNoErr;
-}
-
-static SSLErr cdsaHashClone(SSLBuffer src, SSLBuffer dst)
-{
- cdsaHashContext *srcCtx;
- cdsaHashContext *dstCtx;
- CSSM_RETURN crtn;
-
- CASSERT(src.length >= sizeof(cdsaHashContext));
- CASSERT(dst.length >= sizeof(cdsaHashContext));
- srcCtx = (cdsaHashContext *)src.data;
- dstCtx = (cdsaHashContext *)dst.data;
- dgprintf(("###cdsaHashClone srcCtx %p dstCtx %p\n", srcCtx, dstCtx));
-
- crtn = CSSM_DigestDataClone(srcCtx->hashHand, &dstCtx->hashHand);
- if(crtn) {
- errorLog0("CSSM_DigestDataClone failure\n");
- return SSLCryptoError;
- }
- else {
- return SSLNoErr;
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: hdskcert.c
-
- Contains: certificate request/verify messages
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: hdskcert.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: hdskcert.c Contains support for certificate-related messages
-
- Support for encoding and decoding the certificate, certificate
- request, and certificate verify messages.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _DIGESTS_H_
-#include "digests.h"
-#endif
-
-#ifndef _APPLE_CDSA_H_
-#include "appleCdsa.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#include <string.h>
-#include <assert.h>
-
-SSLErr
-SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx)
-{ SSLErr err;
- UInt32 totalLength;
- int i, j, certCount;
- UInt8 *progress;
- SSLCertificate *cert;
-
- /* Match DER-encoded root certs here */
-
- cert = ctx->localCert;
- CASSERT(cert != 0);
- totalLength = 0;
- certCount = 0;
- while (cert)
- { totalLength += 3 + cert->derCert.length; /* 3 for encoded length field */
- ++certCount;
- cert = cert->next;
- }
-
- certificate->contentType = SSL_handshake;
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- certificate->protocolVersion = ctx->negProtocolVersion;
- if ((err = SSLAllocBuffer(&certificate->contents, totalLength + 7, &ctx->sysCtx)) != 0)
- return err;
-
- progress = certificate->contents.data;
- *progress++ = SSL_certificate;
- progress = SSLEncodeInt(progress, totalLength+3, 3); /* Handshake message length */
- progress = SSLEncodeInt(progress, totalLength, 3); /* Vector length */
-
- /* Root cert is first in the linked list, but has to go last, so walk list backwards */
- for (i = 0; i < certCount; ++i)
- { cert = ctx->localCert;
- for (j = i+1; j < certCount; ++j)
- cert = cert->next;
- progress = SSLEncodeInt(progress, cert->derCert.length, 3);
- memcpy(progress, cert->derCert.data, cert->derCert.length);
- progress += cert->derCert.length;
- }
-
- CASSERT(progress == certificate->contents.data + certificate->contents.length);
-
- if (ctx->protocolSide == SSL_ClientSide)
- ctx->certSent = 1;
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
- UInt32 listLen, certLen;
- UInt8 *p;
- SSLCertificate *cert;
-
- p = message.data;
- listLen = SSLDecodeInt(p,3);
- p += 3;
- if (listLen + 3 != message.length) {
- errorLog0("SSLProcessCertificate: length decode error 1\n");
- return SSLProtocolErr;
- }
-
- while (listLen > 0)
- { certLen = SSLDecodeInt(p,3);
- p += 3;
- if (listLen < certLen + 3) {
- errorLog0("SSLProcessCertificate: length decode error 2\n");
- return SSLProtocolErr;
- }
- cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
- if(cert == NULL) {
- return SSLMemoryErr;
- }
- if ((err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
- { sslFree(cert);
- return err;
- }
- memcpy(cert->derCert.data, p, certLen);
- p += certLen;
- cert->next = ctx->peerCert; /* Insert backwards; root cert will be first in linked list */
- ctx->peerCert = cert;
- listLen -= 3+certLen;
- }
- CASSERT(p == message.data + message.length && listLen == 0);
-
- if (ctx->peerCert == 0)
- return X509CertChainInvalidErr;
-
- if((err = sslVerifyCertChain(ctx, ctx->peerCert)) != 0)
- return err;
-
- /* Server's certificate is the last one in the chain */
- cert = ctx->peerCert;
- while (cert->next != 0)
- cert = cert->next;
- /* Convert its public key to CDSA format */
- if ((err = sslPubKeyFromCert(ctx,
- &cert->derCert,
- &ctx->peerPubKey,
- &ctx->peerPubKeyCsp)) != 0)
- return err;
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx)
-{
- #if !ST_SERVER_MODE_ENABLE
-
- /* cert request only happens in server mode */
- errorLog0("SSLEncodeCertificateRequest called\n");
- return SSLUnsupportedErr;
-
- #else
-
- SSLErr err;
- UInt32 dnListLen, msgLen;
- UInt8 *progress;
- DNListElem *dn;
-
- dnListLen = 0;
- dn = ctx->acceptableDNList;
- CASSERT(dn != NULL);
- while (dn)
- { dnListLen += 2 + dn->derDN.length;
- dn = dn->next;
- }
- msgLen = 1 + 1 + 2 + dnListLen;
-
- request->contentType = SSL_handshake;
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- request->protocolVersion = ctx->negProtocolVersion;
- if ((err = SSLAllocBuffer(&request->contents, msgLen + 4, &ctx->sysCtx)) != 0)
- return err;
-
- progress = request->contents.data;
- *progress++ = SSL_certificate_request;
- progress = SSLEncodeInt(progress, msgLen, 3);
-
- *progress++ = 1; /* one cert type */
- *progress++ = 1; /* RSA-sign type */
- progress = SSLEncodeInt(progress, dnListLen, 2);
- dn = ctx->acceptableDNList;
- while (dn)
- { progress = SSLEncodeInt(progress, dn->derDN.length, 2);
- memcpy(progress, dn->derDN.data, dn->derDN.length);
- progress += dn->derDN.length;
- dn = dn->next;
- }
-
- CASSERT(progress == request->contents.data + request->contents.length);
-
- return SSLNoErr;
- #endif /* ST_SERVER_MODE_ENABLE */
-}
-
-SSLErr
-SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
- int i, dnListLen, dnLen;
- unsigned int typeCount;
- UInt8 *progress;
- SSLBuffer dnBuf;
- DNListElem *dn;
-
- /* cert request only happens in during client authentication, which
- * we don't do */
- errorLog0("SSLProcessCertificateRequest called\n");
- if (message.length < 3) {
- errorLog0("SSLProcessCertificateRequest: length decode error 1\n");
- return ERR(SSLProtocolErr);
- }
- progress = message.data;
- typeCount = *progress++;
- if (typeCount < 1 || message.length < 3 + typeCount) {
- errorLog0("SSLProcessCertificateRequest: length decode error 2\n");
- return ERR(SSLProtocolErr);
- }
- for (i = 0; i < typeCount; i++)
- { if (*progress++ == 1)
- ctx->x509Requested = 1;
- }
-
- dnListLen = SSLDecodeInt(progress, 2);
- progress += 2;
- if (message.length != 3 + typeCount + dnListLen) {
- errorLog0("SSLProcessCertificateRequest: length decode error 3\n");
- return ERR(SSLProtocolErr);
- }
- while (dnListLen > 0)
- { if (dnListLen < 2) {
- errorLog0("SSLProcessCertificateRequest: dnListLen error 1\n");
- return ERR(SSLProtocolErr);
- }
- dnLen = SSLDecodeInt(progress, 2);
- progress += 2;
- if (dnListLen < 2 + dnLen) {
- errorLog0("SSLProcessCertificateRequest: dnListLen error 2\n");
- return ERR(SSLProtocolErr);
- }
- if (ERR(err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem), &ctx->sysCtx)) != 0)
- return err;
- dn = (DNListElem*)dnBuf.data;
- if (ERR(err = SSLAllocBuffer(&dn->derDN, dnLen, &ctx->sysCtx)) != 0)
- { SSLFreeBuffer(&dnBuf, &ctx->sysCtx);
- return err;
- }
- memcpy(dn->derDN.data, progress, dnLen);
- progress += dnLen;
- dn->next = ctx->acceptableDNList;
- ctx->acceptableDNList = dn;
- dnListLen -= 2 + dnLen;
- }
-
- CASSERT(progress == message.data + message.length);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx)
-{ SSLErr err;
- UInt8 signedHashData[36];
- SSLBuffer hashData, shaMsgState, md5MsgState;
- UInt32 len;
- UInt32 outputLen;
-
- certVerify->contents.data = 0;
- hashData.data = signedHashData;
- hashData.length = 36;
-
- if (ERR(err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
- goto fail;
- if (ERR(err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
- goto fail;
- assert(ctx->sslTslCalls != NULL);
- if (ERR(err = ctx->sslTslCalls->computeCertVfyMac(ctx,
- hashData, shaMsgState, md5MsgState)) != 0)
- goto fail;
-
- CASSERT(ctx->signingPrivKey != NULL);
- len = sslKeyLengthInBytes(ctx->signingPrivKey);
-
- certVerify->contentType = SSL_handshake;
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- certVerify->protocolVersion = ctx->negProtocolVersion;
- if (ERR(err = SSLAllocBuffer(&certVerify->contents, len + 6, &ctx->sysCtx)) != 0)
- goto fail;
-
- certVerify->contents.data[0] = SSL_certificate_verify;
- SSLEncodeInt(certVerify->contents.data+1, len+2, 3);
- SSLEncodeInt(certVerify->contents.data+4, len, 2);
-
- err = sslRsaRawSign(ctx,
- ctx->signingPrivKey,
- ctx->signingKeyCsp,
- signedHashData,
- 36, // MD5 size + SHA1 size
- certVerify->contents.data+6,
- len, // we mallocd len+6
- &outputLen);
- if(err) {
- goto fail;
- }
-
- CASSERT(outputLen == len);
-
- err = SSLNoErr;
-
-fail:
- ERR(SSLFreeBuffer(&shaMsgState, &ctx->sysCtx));
- ERR(SSLFreeBuffer(&md5MsgState, &ctx->sysCtx));
-
- return err;
-}
-
-SSLErr
-SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
- UInt8 signedHashData[36];
- UInt16 signatureLen;
- SSLBuffer hashData, shaMsgState, md5MsgState, outputData;
- unsigned int publicModulusLen;
-
- shaMsgState.data = 0;
- md5MsgState.data = 0;
- outputData.data = 0;
-
- if (message.length < 2) {
- errorLog0("SSLProcessCertificateVerify: msg len error\n");
- return ERR(SSLProtocolErr);
- }
-
- signatureLen = (UInt16)SSLDecodeInt(message.data, 2);
- if (message.length != 2 + signatureLen) {
- errorLog0("SSLProcessCertificateVerify: sig len error 1\n");
- return ERR(SSLProtocolErr);
- }
-
- CASSERT(ctx->peerPubKey != NULL);
- publicModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
-
- if (signatureLen != publicModulusLen) {
- errorLog0("SSLProcessCertificateVerify: sig len error 2\n");
- return ERR(SSLProtocolErr);
- }
- outputData.data = 0;
- hashData.data = signedHashData;
- hashData.length = 36;
-
- if (ERR(err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
- goto fail;
- if (ERR(err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
- goto fail;
- assert(ctx->sslTslCalls != NULL);
- if (ERR(err = ctx->sslTslCalls->computeCertVfyMac(ctx, hashData,
- shaMsgState, md5MsgState)) != 0)
- goto fail;
-
- if (ERR(err = SSLAllocBuffer(&outputData, publicModulusLen, &ctx->sysCtx)) != 0)
- goto fail;
-
- /*
- * The CSP does the decrypt & compare for us in one shot
- */
- err = sslRsaRawVerify(ctx,
- ctx->peerPubKey,
- ctx->peerPubKeyCsp, // FIXME - maybe we just use cspHand?
- message.data + 2,
- signatureLen,
- outputData.data,
- 36);
- if(err) {
- goto fail;
- }
- err = SSLNoErr;
-
-fail:
- ERR(SSLFreeBuffer(&shaMsgState, &ctx->sysCtx));
- ERR(SSLFreeBuffer(&md5MsgState, &ctx->sysCtx));
- ERR(SSLFreeBuffer(&outputData, &ctx->sysCtx));
-
- return err;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: hdskchgc.c
-
- Contains: support for change cipher spec messages
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: hdskchgc.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: hdskchgc.c Contains support for change cipher spec messages
-
- Simple support for encoding and decoding change cipher spec messages;
- the decode message also installs the pending read cipher (if it is
- ready).
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#include <assert.h>
-#include <string.h>
-
-SSLErr
-SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx)
-{ SSLErr err;
-
- CASSERT(ctx->writePending.ready);
-
- #if LOG_NEGOTIATE
- dprintf0("===Sending changeCipherSpec msg\n");
- #endif
- rec->contentType = SSL_change_cipher_spec;
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- rec->protocolVersion = ctx->negProtocolVersion;
- rec->contents.length = 1;
- if ((err = SSLAllocBuffer(&rec->contents, 1, &ctx->sysCtx)) != 0)
- return err;
- rec->contents.data[0] = 1;
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx)
-{ SSLErr err;
-
- if (rec.contents.length != 1 || rec.contents.data[0] != 1)
- { SSLFatalSessionAlert(alert_unexpected_message, ctx);
- errorLog2("***bad changeCipherSpec msg: length %d data 0x%x\n",
- (unsigned)rec.contents.length, (unsigned)rec.contents.data[0]);
- return SSLProtocolErr;
- }
-
- if (!ctx->readPending.ready || ctx->state != HandshakeChangeCipherSpec)
- { SSLFatalSessionAlert(alert_unexpected_message, ctx);
- errorLog2("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
- (unsigned)ctx->readPending.ready, (unsigned)ctx->state);
- return SSLProtocolErr;
- }
-
- #if LOG_NEGOTIATE
- dprintf0("===Processing changeCipherSpec msg\n");
- #endif
-
- /* Install new cipher spec on read side */
- if ((err = SSLDisposeCipherSuite(&ctx->readCipher, ctx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return err;
- }
- ctx->readCipher = ctx->readPending;
- ctx->readCipher.ready = 0; /* Can't send data until Finished is sent */
- SSLChangeHdskState(ctx, HandshakeFinished);
- memset(&ctx->readPending, 0, sizeof(CipherContext)); /* Zero out old data */
- return SSLNoErr;
-}
-
-SSLErr
-SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx)
-{ SSLErr err;
-
- /* symmetric key */
- if (cipher->symKey)
- { if ((err = cipher->symCipher->finish(cipher, ctx)) != 0)
- return err;
- cipher->symKey = 0;
- }
-
- /* per-record hash/hmac context */
- ctx->sslTslCalls->freeMac(cipher);
-
- return SSLNoErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: hdskfini.c
-
- Contains: Finished and server hello done messages.
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: hdskfini.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: hdskfini.c Finished and server hello done messages
-
- Support for encoding and decoding finished and server hello done
- messgages. Also includes the necessary calculations for the Finished
- message; note that the same function is used to calculate certificate
- verify message hashes (without the 'SRVR' or 'CLNT' protocol side
- identifier).
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _DIGESTS_H_
-#include "digests.h"
-#endif
-
-#include <string.h>
-#include <assert.h>
-
-SSLErr
-SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer finishedMsg, shaMsgState, md5MsgState;
- Boolean isServerMsg;
- unsigned finishedSize;
-
- shaMsgState.data = 0;
- md5MsgState.data = 0;
-
- /* size and version depend on negotiatedProtocol */
- switch(ctx->negProtocolVersion) {
- case SSL_Version_3_0:
- finished->protocolVersion = SSL_Version_3_0;
- finishedSize = 36;
- break;
- case TLS_Version_1_0:
- finished->protocolVersion = TLS_Version_1_0;
- finishedSize = 12;
- break;
- default:
- assert(0);
- return SSLInternalError;
- }
- finished->contentType = SSL_handshake;
- /* msg = type + 3 bytes len + finishedSize */
- if ((err = SSLAllocBuffer(&finished->contents, finishedSize + 4,
- &ctx->sysCtx)) != 0)
- return err;
-
- finished->contents.data[0] = SSL_finished;
- SSLEncodeInt(finished->contents.data + 1, finishedSize, 3);
-
- finishedMsg.data = finished->contents.data + 4;
- finishedMsg.length = finishedSize;
-
- if ((err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
- goto fail;
- if ((err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
- goto fail;
- isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? true : false;
- if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, finishedMsg,
- shaMsgState, md5MsgState, isServerMsg)) != 0)
- goto fail;
-
-fail:
- SSLFreeBuffer(&shaMsgState, &ctx->sysCtx);
- SSLFreeBuffer(&md5MsgState, &ctx->sysCtx);
- return err;
-}
-
-SSLErr
-SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer expectedFinished, shaMsgState, md5MsgState;
- Boolean isServerMsg;
- unsigned finishedSize;
-
- switch(ctx->negProtocolVersion) {
- case SSL_Version_3_0:
- finishedSize = 36;
- break;
- case TLS_Version_1_0:
- finishedSize = 12;
- break;
- default:
- assert(0);
- return SSLInternalError;
- }
- if (message.length != finishedSize) {
- errorLog0("SSLProcessFinished: msg len error 1\n");
- return SSLProtocolErr;
- }
- expectedFinished.data = 0;
- if ((err = SSLAllocBuffer(&expectedFinished, finishedSize, &ctx->sysCtx)) != 0)
- return err;
- shaMsgState.data = 0;
- if ((err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
- goto fail;
- md5MsgState.data = 0;
- if ((err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
- goto fail;
- isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? false : true;
- if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished,
- shaMsgState, md5MsgState, isServerMsg)) != 0)
- goto fail;
-
- if (memcmp(expectedFinished.data, message.data, finishedSize) != 0)
- {
- errorLog0("SSLProcessFinished: memcmp failure\n");
- err = SSLProtocolErr;
- goto fail;
- }
-
-fail:
- SSLFreeBuffer(&expectedFinished, &ctx->sysCtx);
- SSLFreeBuffer(&shaMsgState, &ctx->sysCtx);
- SSLFreeBuffer(&md5MsgState, &ctx->sysCtx);
- return err;
-}
-
-SSLErr
-SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx)
-{ SSLErr err;
-
- helloDone->contentType = SSL_handshake;
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- helloDone->protocolVersion = ctx->negProtocolVersion;
- if ((err = SSLAllocBuffer(&helloDone->contents, 4, &ctx->sysCtx)) != 0)
- return err;
- helloDone->contents.data[0] = SSL_server_hello_done;
- SSLEncodeInt(helloDone->contents.data+1, 0, 3); /* Message has 0 length */
- return SSLNoErr;
-}
-
-SSLErr
-SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
-{ CASSERT(ctx->protocolSide == SSL_ClientSide);
- if (message.length != 0) {
- errorLog0("SSLProcessServerHelloDone: nonzero msg len\n");
- return SSLProtocolErr;
- }
- return SSLNoErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: hdskhelo.c
-
- Contains: Support for client hello and server hello messages.
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: hdskhelo.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: hdskhelo.c Support for client hello and server hello messages
-
- Also, encoding of Random structures and initializing the message
- hashes used for calculating finished and certificate verify messages.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLSESS_H_
-#include "sslsess.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _APPLE_GLUE_H_
-#include "appleGlue.h"
-#endif
-
-#ifndef _APPLE_CDSA_H_
-#include "appleCdsa.h"
-#endif
-
-#ifndef _DIGESTS_H_
-#include "digests.h"
-#endif
-
-#ifndef _CIPHER_SPECS_H_
-#include "cipherSpecs.h"
-#endif
-
-#include <string.h>
-
-static SSLErr SSLEncodeRandom(unsigned char *p, SSLContext *ctx);
-
-/* IE treats null session id as valid; two consecutive sessions with NULL ID
- * are considered a match. Workaround: when resumable sessions are disabled,
- * send a random session ID. */
-#define SSL_IE_NULL_RESUME_BUG 1
-#if SSL_IE_NULL_RESUME_BUG
-#define SSL_NULL_ID_LEN 32 /* length of bogus session ID */
-#endif
-
-SSLErr
-SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx)
-{ SSLErr err;
- UInt8 *progress;
- int sessionIDLen;
-
- sessionIDLen = 0;
- if (ctx->sessionID.data != 0)
- sessionIDLen = (UInt8)ctx->sessionID.length;
- #if SSL_IE_NULL_RESUME_BUG
- if(sessionIDLen == 0) {
- sessionIDLen = SSL_NULL_ID_LEN;
- }
- #endif /* SSL_IE_NULL_RESUME_BUG */
-
- #if LOG_NEGOTIATE
- dprintf2("===SSL3 server: sending version %d_%d\n",
- ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
- dprintf1("...sessionIDLen = %d\n", sessionIDLen);
- #endif
- serverHello->protocolVersion = ctx->negProtocolVersion;
- serverHello->contentType = SSL_handshake;
- if ((err = SSLAllocBuffer(&serverHello->contents, 42 + sessionIDLen, &ctx->sysCtx)) != 0)
- return err;
-
- progress = serverHello->contents.data;
- *progress++ = SSL_server_hello;
- progress = SSLEncodeInt(progress, 38 + sessionIDLen, 3);
- progress = SSLEncodeInt(progress, serverHello->protocolVersion, 2);
- if ((err = SSLEncodeRandom(progress, ctx)) != 0)
- return err;
- memcpy(ctx->serverRandom, progress, SSL_CLIENT_SRVR_RAND_SIZE);
- progress += SSL_CLIENT_SRVR_RAND_SIZE;
- *(progress++) = (UInt8)sessionIDLen;
- #if SSL_IE_NULL_RESUME_BUG
- if(ctx->sessionID.data != NULL) {
- /* normal path for enabled resumable session */
- memcpy(progress, ctx->sessionID.data, sessionIDLen);
- }
- else {
- /* IE workaround */
- SSLBuffer rb;
- rb.data = progress;
- rb.length = SSL_NULL_ID_LEN;
- sslRand(ctx, &rb);
- }
- #else
- if (sessionIDLen > 0)
- memcpy(progress, ctx->sessionID.data, sessionIDLen);
- #endif /* SSL_IE_NULL_RESUME_BUG */
- progress += sessionIDLen;
- progress = SSLEncodeInt(progress, ctx->selectedCipher, 2);
- *(progress++) = 0; /* Null compression */
-
- #if LOG_NEGOTIATE
- dprintf1("ssl3: server specifying cipherSuite 0x%lx\n", (UInt32)ctx->selectedCipher);
- #endif
-
- CASSERT(progress == serverHello->contents.data + serverHello->contents.length);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
- SSLProtocolVersion protocolVersion;
- unsigned int sessionIDLen;
- UInt8 *p;
-
- CASSERT(ctx->protocolSide == SSL_ClientSide);
-
- if (message.length < 38 || message.length > 70) {
- errorLog0("SSLProcessServerHello: msg len error\n");
- return SSLProtocolErr;
- }
- p = message.data;
-
- protocolVersion = (SSLProtocolVersion)SSLDecodeInt(p, 2);
- p += 2;
- if (protocolVersion > ctx->maxProtocolVersion) {
- return SSLNegotiationErr;
- }
- ctx->negProtocolVersion = protocolVersion;
- switch(protocolVersion) {
- case SSL_Version_3_0:
- ctx->sslTslCalls = &Ssl3Callouts;
- break;
- case TLS_Version_1_0:
- ctx->sslTslCalls = &Tls1Callouts;
- break;
- default:
- return SSLNegotiationErr;
- }
- #if LOG_NEGOTIATE
- dprintf2("===SSL3 client: negVersion is %d_%d\n",
- (protocolVersion >> 8) & 0xff, protocolVersion & 0xff);
- #endif
-
- memcpy(ctx->serverRandom, p, 32);
- p += 32;
-
- sessionIDLen = *p++;
- if (message.length != 38 + sessionIDLen) {
- errorLog0("SSLProcessServerHello: msg len error 2\n");
- return SSLProtocolErr;
- }
- if (sessionIDLen > 0 && ctx->peerID.data != 0)
- { /* Don't die on error; just treat it as an uncached session */
- err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx);
- if (err == 0)
- memcpy(ctx->sessionID.data, p, sessionIDLen);
- }
- p += sessionIDLen;
-
- ctx->selectedCipher = (UInt16)SSLDecodeInt(p,2);
- #if LOG_NEGOTIATE
- dprintf1("===ssl3: server requests cipherKind %d\n",
- (unsigned)ctx->selectedCipher);
- #endif
- p += 2;
- if ((err = FindCipherSpec(ctx)) != 0) {
- return err;
- }
-
- if (*p++ != 0) /* Compression */
- return SSLUnsupportedErr;
-
- CASSERT(p == message.data + message.length);
- return SSLNoErr;
-}
-
-SSLErr
-SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
-{ int length, i;
- SSLErr err;
- unsigned char *p;
- SSLBuffer sessionIdentifier;
- UInt16 sessionIDLen;
-
- CASSERT(ctx->protocolSide == SSL_ClientSide);
-
- sessionIDLen = 0;
- if (ctx->resumableSession.data != 0)
- { if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
- { return err;
- }
- sessionIDLen = sessionIdentifier.length;
- }
-
- length = 39 + 2*(ctx->numValidCipherSpecs) + sessionIDLen;
-
- clientHello->protocolVersion = ctx->maxProtocolVersion;
- clientHello->contentType = SSL_handshake;
- if ((err = SSLAllocBuffer(&clientHello->contents, length + 4, &ctx->sysCtx)) != 0)
- return err;
-
- p = clientHello->contents.data;
- *p++ = SSL_client_hello;
- p = SSLEncodeInt(p, length, 3);
- p = SSLEncodeInt(p, ctx->maxProtocolVersion, 2);
- #if LOG_NEGOTIATE
- dprintf2("===SSL3 client: proclaiming max protocol %d_%d capable ONLY\n",
- ctx->maxProtocolVersion >> 8, ctx->maxProtocolVersion & 0xff);
- #endif
- if ((err = SSLEncodeRandom(p, ctx)) != 0)
- { SSLFreeBuffer(&clientHello->contents, &ctx->sysCtx);
- return err;
- }
- memcpy(ctx->clientRandom, p, SSL_CLIENT_SRVR_RAND_SIZE);
- p += 32;
- *p++ = sessionIDLen; /* 1 byte vector length */
- if (sessionIDLen > 0)
- { memcpy(p, sessionIdentifier.data, sessionIDLen);
- if ((err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
- return err;
- }
- p += sessionIDLen;
- p = SSLEncodeInt(p, 2*(ctx->numValidCipherSpecs), 2); /* 2 byte long vector length */
- for (i = 0; i<ctx->numValidCipherSpecs; ++i)
- p = SSLEncodeInt(p, ctx->validCipherSpecs[i].cipherSpec, 2);
- *p++ = 1; /* 1 byte long vector */
- *p++ = 0; /* null compression */
-
- CASSERT(p == clientHello->contents.data + clientHello->contents.length);
-
- if ((err = SSLInitMessageHashes(ctx)) != 0)
- return err;
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
- SSLProtocolVersion clientVersion;
- UInt16 cipherListLen, cipherCount, desiredSpec, cipherSpec;
- UInt8 sessionIDLen, compressionCount;
- UInt8 *progress;
- int i;
-
- if (message.length < 41) {
- errorLog0("SSLProcessClientHello: msg len error 1\n");
- return SSLProtocolErr;
- }
- progress = message.data;
- clientVersion = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
- progress += 2;
- #if old_way
- /* tested, works with SSLv3 */
- if (clientVersion < SSL_Version_3_0) {
- #if LOG_NEGOTIATE
- dprintf1("===SSL3 server: clientVersion %s rejected\n", clientVersion);
- #endif
- return SSLUnsupportedErr;
- }
- ctx->negProtocolVersion = SSL_Version_3_0;
- #else
- /* Untested, for TLS */
- if(clientVersion > ctx->maxProtocolVersion) {
- clientVersion = ctx->maxProtocolVersion;
- }
- switch(clientVersion) {
- case SSL_Version_3_0:
- ctx->sslTslCalls = &Ssl3Callouts;
- break;
- case TLS_Version_1_0:
- ctx->sslTslCalls = &Tls1Callouts;
- break;
- default:
- return SSLNegotiationErr;
- }
- ctx->negProtocolVersion = clientVersion;
- #endif /* new_way */
- #if LOG_NEGOTIATE
- dprintf2("===SSL3 server: negVersion is %d_%d\n",
- clientVersion >> 8, clientVersion & 0xff);
- #endif
-
- memcpy(ctx->clientRandom, progress, SSL_CLIENT_SRVR_RAND_SIZE);
- progress += 32;
- sessionIDLen = *(progress++);
- if (message.length < 41 + sessionIDLen) {
- errorLog0("SSLProcessClientHello: msg len error 2\n");
- return SSLProtocolErr;
- }
- if (sessionIDLen > 0 && ctx->peerID.data != 0)
- { /* Don't die on error; just treat it as an uncacheable session */
- err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx);
- if (err == 0)
- memcpy(ctx->sessionID.data, progress, sessionIDLen);
- }
- progress += sessionIDLen;
-
- cipherListLen = (UInt16)SSLDecodeInt(progress, 2); /* Count of cipherSpecs, must be even & >= 2 */
- progress += 2;
- if ((cipherListLen & 1) || cipherListLen < 2 || message.length < 39 + sessionIDLen + cipherListLen) {
- errorLog0("SSLProcessClientHello: msg len error 3\n");
- return SSLProtocolErr;
- }
- cipherCount = cipherListLen/2;
- cipherSpec = 0xFFFF; /* No match marker */
- while (cipherSpec == 0xFFFF && cipherCount--)
- { desiredSpec = (UInt16)SSLDecodeInt(progress, 2);
- progress += 2;
- for (i = 0; i <ctx->numValidCipherSpecs; i++)
- { if (ctx->validCipherSpecs[i].cipherSpec == desiredSpec)
- { cipherSpec = desiredSpec;
- break;
- }
- }
- }
-
- if (cipherSpec == 0xFFFF)
- return SSLNegotiationErr;
- progress += 2 * cipherCount; /* Advance past unchecked cipherCounts */
- ctx->selectedCipher = cipherSpec;
- if ((err = FindCipherSpec(ctx)) != 0) {
- return err;
- }
- #if LOG_NEGOTIATE
- dprintf1("ssl3 server: selecting cipherKind 0x%x\n", (unsigned)ctx->selectedCipher);
- #endif
-
- compressionCount = *(progress++);
-/* message.length restriction relaxed to allow too-long messages for future expansion
- following recommendation of TLS meeting 5/29/96 */
- if (compressionCount < 1 || message.length < 38 + sessionIDLen + cipherListLen + compressionCount) {
- errorLog0("SSLProcessClientHello: msg len error 4\n");
- return SSLProtocolErr;
- }
- /* Ignore list; we're doing null */
-
- if ((err = SSLInitMessageHashes(ctx)) != 0)
- return err;
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLEncodeRandom(unsigned char *p, SSLContext *ctx)
-{ SSLBuffer randomData;
- SSLErr err;
- UInt32 time;
-
- if ((err = sslTime(&time)) != 0)
- return err;
- SSLEncodeInt(p, time, 4);
- randomData.data = p+4;
- randomData.length = 28;
- if((err = sslRand(ctx, &randomData)) != 0)
- return err;
- return SSLNoErr;
-}
-
-SSLErr
-SSLInitMessageHashes(SSLContext *ctx)
-{ SSLErr err;
-
- if ((err = CloseHash(&SSLHashSHA1, &ctx->shaState, ctx)) != 0)
- return err;
- if ((err = CloseHash(&SSLHashMD5, &ctx->md5State, ctx)) != 0)
- return err;
- if ((err = ReadyHash(&SSLHashSHA1, &ctx->shaState, ctx)) != 0)
- return err;
- if ((err = ReadyHash(&SSLHashMD5, &ctx->md5State, ctx)) != 0)
- return err;
- return SSLNoErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: hdskkeys.c
-
- Contains: Key calculation and encoding
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: hdskkeys.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: hdskkeys.c Key calculation and encoding
-
- Contains code for encoding premaster secrets, generating master
- secrets from premaster secrets & key data generation from master
- secrets and following initialization of ciphers.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _APPLE_CDSA_H_
-#include "appleCdsa.h"
-#endif
-
-#ifndef _DIGESTS_H_
-#include "digests.h"
-#endif
-
-#include <string.h>
-#include <assert.h>
-
-SSLErr
-SSLEncodeRSAPremasterSecret(SSLContext *ctx)
-{ SSLBuffer randData;
- SSLErr err;
-
- if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret,
- SSL_RSA_PREMASTER_SECRET_SIZE, &ctx->sysCtx)) != 0)
- return err;
-
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- SSLEncodeInt(ctx->preMasterSecret.data, ctx->maxProtocolVersion, 2);
- randData.data = ctx->preMasterSecret.data+2;
- randData.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
- if ((err = sslRand(ctx, &randData)) != 0)
- return err;
-
- DUMP_BUFFER_NAME("premaster secret", ctx->preMasterSecret);
-
- return SSLNoErr;
-}
-
-#if APPLE_DH
-
-SSLErr
-SSLEncodeDHPremasterSecret(SSLContext *ctx)
-{
- #if !APPLE_DH
- return SSLUnsupportedErr;
- #else
-
- SSLErr err;
- int rsaResult;
- SSLRandomCtx rsaRandom;
-
-/* Given the server's Diffie-Hellman parameters, prepare a public & private value,
- * then use the public value provided by the server and our private value to
- * generate a shared key (the premaster secret). Save our public value in
- * ctx->dhExchangePublic to send to the server so it can calculate the matching
- * key on its end
- */
- if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
- return err;
-
-#if RSAREF
- { privateValue.data = 0;
-
- if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
- goto fail;
- if (ERR(err = SSLAllocBuffer(&privateValue, ctx->dhExchangePublic.length - 16, &ctx->sysCtx)) != 0)
- goto fail;
-
- if ((rsaResult = R_SetupDHAgreement(ctx->dhExchangePublic.data, privateValue.data,
- privateValue.length, &ctx->peerDHParams, &rsaRandom)) != 0)
- { err = SSLUnknownErr;
- goto fail;
- }
-
- if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
- goto fail;
-
- if ((rsaResult = R_ComputeDHAgreedKey (ctx->preMasterSecret.data, ctx->dhPeerPublic.data,
- privateValue.data, privateValue.length, &ctx->peerDHParams)) != 0)
- { err = SSLUnknownErr;
- goto fail;
- }
- }
-#elif BSAFE
- { unsigned int outputLen;
-
- if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, 128, &ctx->sysCtx)) != 0)
- goto fail;
- if ((rsaResult = B_KeyAgreePhase1(ctx->peerDHParams, ctx->dhExchangePublic.data,
- &outputLen, 128, rsaRandom, NO_SURR)) != 0)
- { err = SSLUnknownErr;
- goto fail;
- }
- ctx->dhExchangePublic.length = outputLen;
- if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 128, &ctx->sysCtx)) != 0)
- goto fail;
- if ((rsaResult = B_KeyAgreePhase2(ctx->peerDHParams, ctx->preMasterSecret.data,
- &outputLen, 128, ctx->dhPeerPublic.data, ctx->dhPeerPublic.length,
- NO_SURR)) != 0)
- { err = SSLUnknownErr;
- goto fail;
- }
- ctx->preMasterSecret.length = outputLen;
- }
- #endif
-
- DUMP_BUFFER_NAME("premaster secret", ctx->preMasterSecret);
-
- err = SSLNoErr;
-fail:
-#if RSAREF
- ERR(SSLFreeBuffer(&privateValue, &ctx->sysCtx));
- R_RandomFinal(&rsaRandom);
-#elif BSAFE
- B_DestroyAlgorithmObject(&rsaRandom);
-#endif
- return err;
- #endif
-}
-
-#endif /* APPLE_DH */
-
-SSLErr
-SSLInitPendingCiphers(SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer key;
- UInt8 *keyDataProgress, *keyPtr, *ivPtr;
- int keyDataLen;
- CipherContext *serverPending, *clientPending;
-
- key.data = 0;
-
- ctx->readPending.macRef = ctx->selectedCipherSpec->macAlgorithm;
- ctx->writePending.macRef = ctx->selectedCipherSpec->macAlgorithm;
- ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
- ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
- ctx->readPending.sequenceNum.high = ctx->readPending.sequenceNum.low = 0;
- ctx->writePending.sequenceNum.high = ctx->writePending.sequenceNum.low = 0;
-
- keyDataLen = ctx->selectedCipherSpec->macAlgorithm->hash->digestSize +
- ctx->selectedCipherSpec->cipher->secretKeySize;
- if (ctx->selectedCipherSpec->isExportable == NotExportable)
- keyDataLen += ctx->selectedCipherSpec->cipher->ivSize;
- keyDataLen *= 2; /* two of everything */
-
- if ((err = SSLAllocBuffer(&key, keyDataLen, &ctx->sysCtx)) != 0)
- return err;
- assert(ctx->sslTslCalls != NULL);
- if ((err = ctx->sslTslCalls->generateKeyMaterial(key, ctx)) != 0)
- goto fail;
-
- if (ctx->protocolSide == SSL_ServerSide)
- { serverPending = &ctx->writePending;
- clientPending = &ctx->readPending;
- }
- else
- { serverPending = &ctx->readPending;
- clientPending = &ctx->writePending;
- }
-
- keyDataProgress = key.data;
- memcpy(clientPending->macSecret, keyDataProgress,
- ctx->selectedCipherSpec->macAlgorithm->hash->digestSize);
- keyDataProgress += ctx->selectedCipherSpec->macAlgorithm->hash->digestSize;
- memcpy(serverPending->macSecret, keyDataProgress,
- ctx->selectedCipherSpec->macAlgorithm->hash->digestSize);
- keyDataProgress += ctx->selectedCipherSpec->macAlgorithm->hash->digestSize;
-
- /* init the reusable-per-record MAC contexts */
- err = ctx->sslTslCalls->initMac(clientPending, ctx);
- if(err) {
- goto fail;
- }
- err = ctx->sslTslCalls->initMac(serverPending, ctx);
- if(err) {
- goto fail;
- }
-
- if (ctx->selectedCipherSpec->isExportable == NotExportable)
- { keyPtr = keyDataProgress;
- keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
- /* Skip server write key to get to IV */
- ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->secretKeySize;
- /* APPLE_CDSA changes to all symmetric cipher routines.....*/
- if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
- clientPending, ctx)) != 0)
- goto fail;
- keyPtr = keyDataProgress;
- keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
- /* Skip client write IV to get to server write IV */
- ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->ivSize;
- if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
- serverPending, ctx)) != 0)
- goto fail;
- }
- else {
- UInt8 clientExportKey[16], serverExportKey[16],
- clientExportIV[16], serverExportIV[16];
- SSLBuffer clientWrite, serverWrite;
- SSLBuffer finalClientWrite, finalServerWrite;
- SSLBuffer finalClientIV, finalServerIV;
-
- assert(ctx->selectedCipherSpec->cipher->keySize <= 16);
- assert(ctx->selectedCipherSpec->cipher->ivSize <= 16);
-
- /* Inputs to generateExportKeyAndIv are clientRandom, serverRandom,
- * clientWriteKey, serverWriteKey. The first two are already present
- * in ctx.
- * Outputs are a key and IV for each of {server, client}.
- */
- clientWrite.data = keyDataProgress;
- clientWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
- serverWrite.data = keyDataProgress + clientWrite.length;
- serverWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
- finalClientWrite.data = clientExportKey;
- finalServerWrite.data = serverExportKey;
- finalClientIV.data = clientExportIV;
- finalServerIV.data = serverExportIV;
- finalClientWrite.length = 16;
- finalServerWrite.length = 16;
- /* these can be zero */
- finalClientIV.length = ctx->selectedCipherSpec->cipher->ivSize;
- finalServerIV.length = ctx->selectedCipherSpec->cipher->ivSize;
-
- assert(ctx->sslTslCalls != NULL);
- err = ctx->sslTslCalls->generateExportKeyAndIv(ctx, clientWrite, serverWrite,
- finalClientWrite, finalServerWrite, finalClientIV, finalServerIV);
- if(err) {
- goto fail;
- }
- if ((err = ctx->selectedCipherSpec->cipher->initialize(clientExportKey,
- clientExportIV, clientPending, ctx)) != 0)
- goto fail;
- if ((err = ctx->selectedCipherSpec->cipher->initialize(serverExportKey,
- serverExportIV, serverPending, ctx)) != 0)
- goto fail;
- }
-
- /* Ciphers are ready for use */
- ctx->writePending.ready = 1;
- ctx->readPending.ready = 1;
-
- /* Ciphers get swapped by sending or receiving a change cipher spec message */
-
- err = SSLNoErr;
-fail:
- SSLFreeBuffer(&key, &ctx->sysCtx);
- return err;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: hdskkyex.c
-
- Contains: Support for key exchange and server key exchange
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: hdskkyex.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: hdskkyex.c Support for key exchange and server key exchange
-
- Encoding and decoding of key exchange and server key exchange
- messages in both the Diffie-Hellman and RSA variants; also, includes
- the necessary crypto library calls to support this negotiation.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _APPLE_CDSA_H_
-#include "appleCdsa.h"
-#endif
-
-#ifndef _DIGESTS_H_
-#include "digests.h"
-#endif
-
-#include <assert.h>
-#include <string.h>
-
-/*
- * Client RSA Key Exchange msgs actually start with a two-byte
- * length field, contrary to the first version of RFC 2246, dated
- * January 1999. See RFC 2246, March 2002, section 7.4.7.1 for
- * updated requirements.
- */
-#define RSA_CLIENT_KEY_ADD_LENGTH 1
-
-typedef CSSM_KEY_PTR SSLRSAPrivateKey;
-
-static SSLErr SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
-static SSLErr SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx);
-static SSLErr SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx);
-static SSLErr SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
-static SSLErr SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
-#if APPLE_DH
-static SSLErr SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
-static SSLErr SSLEncodeDHanonKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
-static SSLErr SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
-static SSLErr SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx);
-#endif
-
-SSLErr
-SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
-{ SSLErr err;
-
- switch (ctx->selectedCipherSpec->keyExchangeMethod)
- { case SSL_RSA:
- case SSL_RSA_EXPORT:
- if (ERR(err = SSLEncodeRSAServerKeyExchange(keyExch, ctx)) != 0)
- return err;
- break;
- #if APPLE_DH
- case SSL_DH_anon:
- if (ERR(err = SSLEncodeDHanonServerKeyExchange(keyExch, ctx)) != 0)
- return err;
- break;
- #endif
- default:
- return ERR(SSLUnsupportedErr);
- }
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
-{ SSLErr err;
- UInt8 *progress;
- int length;
- UInt32 outputLen, localKeyModulusLen;
- UInt8 hashes[36];
- SSLBuffer exportKey,clientRandom,serverRandom,hashCtx, hash;
-
- exportKey.data = 0;
- hashCtx.data = 0;
-
- /* we have a public key here... */
- CASSERT(ctx->encryptPubKey != NULL);
- CASSERT(ctx->protocolSide == SSL_ServerSide);
-
- if ((err = SSLEncodeRSAKeyParams(&exportKey, &ctx->encryptPubKey, ctx)) != 0)
- goto fail;
-
- CASSERT(ctx->signingPubKey != NULL);
- localKeyModulusLen = sslKeyLengthInBytes(ctx->signingPubKey);
-
- length = exportKey.length + 2 + localKeyModulusLen; /* RSA ouputs a block as long as the modulus */
-
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- keyExch->protocolVersion = ctx->negProtocolVersion;
- keyExch->contentType = SSL_handshake;
- if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
- goto fail;
-
- progress = keyExch->contents.data;
- *progress++ = SSL_server_key_exchange;
- progress = SSLEncodeInt(progress, length, 3);
-
- memcpy(progress, exportKey.data, exportKey.length);
- progress += exportKey.length;
-
- clientRandom.data = ctx->clientRandom;
- clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- serverRandom.data = ctx->serverRandom;
- serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
-
- hash.data = &hashes[0];
- hash.length = 16;
- if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.update(hashCtx, exportKey)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.final(hashCtx, hash)) != 0)
- goto fail;
- if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
- goto fail;
-
- hash.data = &hashes[16];
- hash.length = 20;
- if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.update(hashCtx, exportKey)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.final(hashCtx, hash)) != 0)
- goto fail;
- if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
- goto fail;
-
- progress = SSLEncodeInt(progress, localKeyModulusLen, 2);
- err = sslRsaRawSign(ctx,
- ctx->signingPrivKey,
- ctx->signingKeyCsp,
- hashes,
- 36,
- progress,
- length,
- &outputLen);
- if(err) {
- goto fail;
- }
- CASSERT(outputLen == localKeyModulusLen);
-
- err = SSLNoErr;
-
-fail:
- ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
- ERR(SSLFreeBuffer(&exportKey, &ctx->sysCtx));
-
- return err;
-}
-
-static SSLErr
-SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer modulus, exponent;
- UInt8 *progress;
-
- err = sslGetPubKeyBits(ctx,
- *key,
- ctx->encryptKeyCsp,
- &modulus,
- &exponent);
- if(err) {
- SSLFreeBuffer(&modulus, &ctx->sysCtx);
- SSLFreeBuffer(&exponent, &ctx->sysCtx);
- return err;
- }
-
- if (ERR(err = SSLAllocBuffer(keyParams, modulus.length + exponent.length + 4, &ctx->sysCtx)) != 0)
- return err;
- progress = keyParams->data;
- progress = SSLEncodeInt(progress, modulus.length, 2);
- memcpy(progress, modulus.data, modulus.length);
- progress += modulus.length;
- progress = SSLEncodeInt(progress, exponent.length, 2);
- memcpy(progress, exponent.data, exponent.length);
-
- /* these were mallocd by sslGetPubKeyBits() */
- SSLFreeBuffer(&modulus, &ctx->sysCtx);
- SSLFreeBuffer(&exponent, &ctx->sysCtx);
- return SSLNoErr;
-}
-
-#if APPLE_DH
-static SSLErr
-SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
-{ SSLErr err;
- UInt32 length;
- UInt8 *progress;
- SSLRandomCtx random;
- int rsaErr;
-
-#if RSAREF
- length = 6 + ctx->dhAnonParams.primeLen + ctx->dhAnonParams.generatorLen +
- ctx->dhExchangePublic.length;
-
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- keyExch->protocolVersion = ctx->negProtocolVersion;
- keyExch->contentType = SSL_handshake;
- if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
- return err;
-
- progress = keyExch->contents.data;
- *progress++ = SSL_server_key_exchange;
- progress = SSLEncodeInt(progress, length, 3);
-
- progress = SSLEncodeInt(progress, ctx->dhAnonParams.primeLen, 2);
- memcpy(progress, ctx->dhAnonParams.prime, ctx->dhAnonParams.primeLen);
- progress += ctx->dhAnonParams.primeLen;
-
- progress = SSLEncodeInt(progress, ctx->dhAnonParams.generatorLen, 2);
- memcpy(progress, ctx->dhAnonParams.generator, ctx->dhAnonParams.generatorLen);
- progress += ctx->dhAnonParams.generatorLen;
-
- if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
- return err;
- if (ERR(err = SSLAllocBuffer(&ctx->dhPrivate, ctx->dhExchangePublic.length - 16, &ctx->sysCtx)) != 0)
- return err;
-
- if (ERR(err = ReadyRandom(&random, ctx)) != 0)
- return err;
-
- if ((rsaErr = R_SetupDHAgreement(ctx->dhExchangePublic.data, ctx->dhPrivate.data,
- ctx->dhPrivate.length, &ctx->dhAnonParams, &random)) != 0)
- { err = SSLUnknownErr;
- return err;
- }
-
- progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
- memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
- progress += ctx->dhExchangePublic.length;
-
-#elif BSAFE
- { A_DH_KEY_AGREE_PARAMS *params;
- unsigned int outputLen;
-
- if ((rsaErr = B_GetAlgorithmInfo((POINTER*)¶ms, ctx->dhAnonParams, AI_DHKeyAgree)) != 0)
- return SSLUnknownErr;
- if (ERR(err = ReadyRandom(&random, ctx)) != 0)
- return err;
- if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, 128, &ctx->sysCtx)) != 0)
- return err;
- if ((rsaErr = B_KeyAgreePhase1(ctx->dhAnonParams, ctx->dhExchangePublic.data,
- &outputLen, 128, random, NO_SURR)) != 0)
- { err = SSLUnknownErr;
- return err;
- }
- ctx->dhExchangePublic.length = outputLen;
-
- length = 6 + params->prime.len + params->base.len + ctx->dhExchangePublic.length;
-
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- keyExch->protocolVersion = ctx->negProtocolVersion;
- keyExch->contentType = SSL_handshake;
- if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
- return err;
-
- progress = keyExch->contents.data;
- *progress++ = SSL_server_key_exchange;
- progress = SSLEncodeInt(progress, length, 3);
-
- progress = SSLEncodeInt(progress, params->prime.len, 2);
- memcpy(progress, params->prime.data, params->prime.len);
- progress += params->prime.len;
-
- progress = SSLEncodeInt(progress, params->base.len, 2);
- memcpy(progress, params->base.data, params->base.len);
- progress += params->base.len;
-
- progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
- memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
- progress += ctx->dhExchangePublic.length;
- }
-#endif /* RSAREF / BSAFE */
-
- ASSERT(progress == keyExch->contents.data + keyExch->contents.length);
-
- return SSLNoErr;
-}
-
-#endif /* APPLE_DH */
-
-SSLErr
-SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
-
- switch (ctx->selectedCipherSpec->keyExchangeMethod)
- { case SSL_RSA:
- case SSL_RSA_EXPORT:
- if (ERR(err = SSLProcessRSAServerKeyExchange(message, ctx)) != 0)
- return err;
- break;
- #if APPLE_DH
- case SSL_DH_anon:
- if (ERR(err = SSLProcessDHanonServerKeyExchange(message, ctx)) != 0)
- return err;
- break;
- #endif
- default:
- return ERR(SSLUnsupportedErr);
- }
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx)
-{
- SSLErr err;
- SSLBuffer tempPubKey, hashOut, hashCtx, clientRandom, serverRandom;
- UInt16 modulusLen, exponentLen, signatureLen;
- UInt8 *progress, *modulus, *exponent, *signature;
- UInt8 hash[36];
- SSLBuffer signedHashes;
-
- signedHashes.data = 0;
- hashCtx.data = 0;
-
- if (message.length < 2) {
- errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
- return ERR(SSLProtocolErr);
- }
- progress = message.data;
- modulusLen = SSLDecodeInt(progress, 2);
- modulus = progress + 2;
- progress += 2+modulusLen;
- if (message.length < 4 + modulusLen) {
- errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
- return ERR(SSLProtocolErr);
- }
- exponentLen = SSLDecodeInt(progress, 2);
- exponent = progress + 2;
- progress += 2+exponentLen;
- if (message.length < 6 + modulusLen + exponentLen) {
- errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
- return ERR(SSLProtocolErr);
- }
- signatureLen = SSLDecodeInt(progress, 2);
- signature = progress + 2;
- if (message.length != 6 + modulusLen + exponentLen + signatureLen) {
- errorLog0("SSLProcessRSAServerKeyExchange: msg len error 3\n");
- return ERR(SSLProtocolErr);
- }
-
- clientRandom.data = ctx->clientRandom;
- clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- serverRandom.data = ctx->serverRandom;
- serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- tempPubKey.data = message.data;
- tempPubKey.length = modulusLen + exponentLen + 4;
- hashOut.data = hash;
-
- hashOut.length = 16;
- if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.update(hashCtx, tempPubKey)) != 0)
- goto fail;
- if (ERR(err = SSLHashMD5.final(hashCtx, hashOut)) != 0)
- goto fail;
-
- /*
- * SHA hash goes right after the MD5 hash
- */
- hashOut.data = hash + 16;
- hashOut.length = 20;
- if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
- goto fail;
-
- if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.update(hashCtx, tempPubKey)) != 0)
- goto fail;
- if (ERR(err = SSLHashSHA1.final(hashCtx, hashOut)) != 0)
- goto fail;
-
- err = sslRsaRawVerify(ctx,
- ctx->peerPubKey,
- ctx->peerPubKeyCsp,
- hash, /* plaintext */
- 36, /* plaintext length */
- signature,
- signatureLen);
- if(err) {
- errorLog1("SSLProcessRSAServerKeyExchange: sslRsaRawVerify returned %d\n",
- err);
- goto fail;
- }
-
- /* Signature matches; now replace server key with new key */
- {
- SSLBuffer modBuf;
- SSLBuffer expBuf;
-
- /* first free existing peerKey */
- sslFreeKey(ctx->peerPubKeyCsp,
- &ctx->peerPubKey,
- NULL); /* no KCItem */
-
- /* and cook up a new one from raw bits */
- modBuf.data = modulus;
- modBuf.length = modulusLen;
- expBuf.data = exponent;
- expBuf.length = exponentLen;
- err = sslGetPubKeyFromBits(ctx,
- &modBuf,
- &expBuf,
- &ctx->peerPubKey,
- &ctx->peerPubKeyCsp);
- }
-fail:
- ERR(SSLFreeBuffer(&signedHashes, &ctx->sysCtx));
- ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
- return err;
-}
-
-#if APPLE_DH
-static SSLErr
-SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
-{ SSLErr err;
- UInt8 *progress;
- unsigned int totalLength;
-
- if (message.length < 6) {
- errorLog1("SSLProcessDHanonServerKeyExchange error: msg len %d\n",
- message.length);
- return ERR(SSLProtocolErr);
- }
- progress = message.data;
- totalLength = 0;
-
-#if RSAREF
- { SSLBuffer alloc;
- UInt8 *prime, *generator, *publicVal;
-
- ctx->peerDHParams.primeLen = SSLDecodeInt(progress, 2);
- progress += 2;
- prime = progress;
- progress += ctx->peerDHParams.primeLen;
- totalLength += ctx->peerDHParams.primeLen;
- if (message.length < 6 + totalLength)
- return ERR(SSLProtocolErr);
-
- ctx->peerDHParams.generatorLen = SSLDecodeInt(progress, 2);
- progress += 2;
- generator = progress;
- progress += ctx->peerDHParams.generatorLen;
- totalLength += ctx->peerDHParams.generatorLen;
- if (message.length < 6 + totalLength)
- return ERR(SSLProtocolErr);
-
- ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
- progress += 2;
- publicVal = progress;
- progress += ctx->dhPeerPublic.length;
- totalLength += ctx->dhPeerPublic.length;
- if (message.length != 6 + totalLength)
- return ERR(SSLProtocolErr);
-
- ASSERT(progress == message.data + message.length);
-
- if (ERR(err = SSLAllocBuffer(&alloc, ctx->peerDHParams.primeLen +
- ctx->peerDHParams.generatorLen, &ctx->sysCtx)) != 0)
- return err;
-
- ctx->peerDHParams.prime = alloc.data;
- memcpy(ctx->peerDHParams.prime, prime, ctx->peerDHParams.primeLen);
- ctx->peerDHParams.generator = alloc.data + ctx->peerDHParams.primeLen;
- memcpy(ctx->peerDHParams.generator, generator, ctx->peerDHParams.generatorLen);
-
- if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic,
- ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
- return err;
-
- memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
- }
-#elif BSAFE
- { int rsaErr;
- unsigned char *publicVal;
- A_DH_KEY_AGREE_PARAMS params;
- B_ALGORITHM_METHOD *chooser[] = { &AM_DH_KEY_AGREE, 0 };
-
- params.prime.len = SSLDecodeInt(progress, 2);
- progress += 2;
- params.prime.data = progress;
- progress += params.prime.len;
- totalLength += params.prime.len;
- if (message.length < 6 + totalLength)
- return ERR(SSLProtocolErr);
-
- params.base.len = SSLDecodeInt(progress, 2);
- progress += 2;
- params.base.data = progress;
- progress += params.base.len;
- totalLength += params.base.len;
- if (message.length < 6 + totalLength)
- return ERR(SSLProtocolErr);
-
- ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
- if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic, ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
- return err;
-
- progress += 2;
- publicVal = progress;
- progress += ctx->dhPeerPublic.length;
- totalLength += ctx->dhPeerPublic.length;
- memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
- if (message.length != 6 + totalLength)
- return ERR(SSLProtocolErr);
-
- params.exponentBits = 8 * ctx->dhPeerPublic.length - 1;
-
- if ((rsaErr = B_CreateAlgorithmObject(&ctx->peerDHParams)) != 0)
- return SSLUnknownErr;
- if ((rsaErr = B_SetAlgorithmInfo(ctx->peerDHParams, AI_DHKeyAgree, (POINTER)¶ms)) != 0)
- return SSLUnknownErr;
- if ((rsaErr = B_KeyAgreeInit(ctx->peerDHParams, (B_KEY_OBJ) 0, chooser, NO_SURR)) != 0)
- return SSLUnknownErr;
- }
-#endif
-
- return SSLNoErr;
-}
-
-#endif
-
-SSLErr
-SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
-{ SSLErr err;
-
- switch (ctx->selectedCipherSpec->keyExchangeMethod)
- { case SSL_RSA:
- case SSL_RSA_EXPORT:
- if (ERR(err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0)
- return err;
- break;
- #if APPLE_DH
- case SSL_DH_anon:
- if (ERR(err = SSLDecodeDHanonKeyExchange(keyExchange, ctx)) != 0)
- return err;
- break;
- #endif
- default:
- return ERR(SSLUnsupportedErr);
- }
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer result;
- UInt32 outputLen, localKeyModulusLen;
- CSSM_KEY_PTR *key;
- SSLProtocolVersion version;
- Boolean useEncryptKey = false;
- UInt8 *src = NULL;
-
-
- /* different key names, also need CSP handle */
- CSSM_CSP_HANDLE cspHand;
-
- CASSERT(ctx->protocolSide == SSL_ServerSide);
-
- /*
- * FIXME - The original SSLRef looked at
- * ctx->selectedCipherSpec->keyExchangeMethod to decide which
- * key to use (exportKey or localKey). I really don't think we
- * want to use that - it's constant. We need to look at
- * whether the app specified encrypting certs, right?
- */
- #if SSL_SERVER_KEYEXCH_HACK
- /*
- * the way we work with Netscape.
- * FIXME - maybe we should *require* an encryptPrivKey in this
- * situation?
- */
- if((ctx->selectedCipherSpec->keyExchangeMethod == SSL_RSA_EXPORT) &&
- (ctx->encryptPrivKey != NULL)) {
- useEncryptKey = true;
- }
-
- #else /* !SSL_SERVER_KEYEXCH_HACK */
- /* The "correct" way, I think, which doesn't work with Netscape */
- if (ctx->encryptPrivKey) {
- useEncryptKey = true;
- }
- #endif /* SSL_SERVER_KEYEXCH_HACK */
- if (useEncryptKey) {
- key = &ctx->encryptPrivKey;
- cspHand = ctx->encryptKeyCsp;
- }
- else {
- key = &ctx->signingPrivKey;
- cspHand = ctx->signingKeyCsp;
- }
-
- localKeyModulusLen = sslKeyLengthInBytes(*key);
-
- /*
- * We have to tolerate incoming key exchange msgs with and without the
- * two-byte "encrypted length" field.
- */
- if (keyExchange.length == localKeyModulusLen) {
- /* no length encoded */
- src = keyExchange.data;
- }
- else if((keyExchange.length == (localKeyModulusLen + 2)) &&
- (ctx->negProtocolVersion >= TLS_Version_1_0)) {
- /* TLS only - skip the length bytes */
- src = keyExchange.data + 2;
- }
- else {
- errorLog2("SSLDecodeRSAKeyExchange: length error (exp %u got %u)\n",
- (unsigned)localKeyModulusLen, (unsigned)keyExchange.length);
- return ERR(SSLProtocolErr);
- }
- err = SSLAllocBuffer(&result, localKeyModulusLen, &ctx->sysCtx);
- if(err != 0) {
- return err;
- }
-
- err = sslRsaDecrypt(ctx,
- *key,
- cspHand,
- src,
- localKeyModulusLen,
- result.data,
- 48,
- &outputLen);
- if(err) {
- goto fail;
- }
-
- if (outputLen != 48)
- {
- errorLog0("SSLDecodeRSAKeyExchange: outputLen error\n");
- ERR(err = SSLProtocolErr);
- goto fail;
- }
- result.length = outputLen;
-
- version = (SSLProtocolVersion)SSLDecodeInt(result.data, 2);
-/* Modify this check to check against our maximum version with protocol revisions */
- if (version > ctx->negProtocolVersion && version < SSL_Version_3_0) {
- errorLog0("SSLDecodeRSAKeyExchange: version error\n");
- ERR(err = SSLProtocolErr);
- goto fail;
- }
- if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret,
- SSL_RSA_PREMASTER_SECRET_SIZE, &ctx->sysCtx)) != 0)
- goto fail;
- memcpy(ctx->preMasterSecret.data, result.data,
- SSL_RSA_PREMASTER_SECRET_SIZE);
-
- err = SSLNoErr;
-fail:
- ERR(SSLFreeBuffer(&result, &ctx->sysCtx));
- return err;
-}
-
-#if APPLE_DH
-static SSLErr
-SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
-{ SSLErr err;
- unsigned int publicLen;
- int rsaResult;
-
- publicLen = SSLDecodeInt(keyExchange.data, 2);
-
-#if RSAREF
- if (keyExchange.length != publicLen + 2 ||
- publicLen != ctx->dhAnonParams.primeLen)
- return ERR(SSLProtocolErr);
-
- if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, ctx->dhAnonParams.primeLen, &ctx->sysCtx)) != 0)
- return err;
-
- if ((rsaResult = R_ComputeDHAgreedKey (ctx->preMasterSecret.data, ctx->dhPeerPublic.data,
- ctx->dhPrivate.data, ctx->dhPrivate.length, &ctx->dhAnonParams)) != 0)
- { err = SSLUnknownErr;
- return err;
- }
-
-#elif BSAFE
- { unsigned int amount;
- if (keyExchange.length != publicLen + 2)
- return ERR(SSLProtocolErr);
-
- if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 128, &ctx->sysCtx)) != 0)
- return err;
-
- if ((rsaResult = B_KeyAgreePhase2(ctx->dhAnonParams, ctx->preMasterSecret.data,
- &amount, 128, keyExchange.data+2, publicLen, NO_SURR)) != 0)
- return err;
-
- ctx->preMasterSecret.length = amount;
- }
-#endif
-
- return SSLNoErr;
-}
-#endif /* APPLE_DH */
-
-SSLErr
-SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
-{ SSLErr err;
-
- CASSERT(ctx->protocolSide == SSL_ClientSide);
-
- switch (ctx->selectedCipherSpec->keyExchangeMethod)
- { case SSL_RSA:
- case SSL_RSA_EXPORT:
- if (ERR(err = SSLEncodeRSAKeyExchange(keyExchange, ctx)) != 0)
- return err;
- break;
- #if APPLE_DH
- case SSL_DH_anon:
- if (ERR(err = SSLEncodeDHanonKeyExchange(keyExchange, ctx)) != 0)
- return err;
- break;
- #endif
- default:
- return ERR(SSLUnsupportedErr);
- }
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
-{ SSLErr err;
- UInt32 outputLen, peerKeyModulusLen;
- UInt32 bufLen;
- UInt8 *dst;
- bool encodeLen = false;
-
- if (ERR(err = SSLEncodeRSAPremasterSecret(ctx)) != 0)
- return err;
-
- keyExchange->contentType = SSL_handshake;
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- keyExchange->protocolVersion = ctx->negProtocolVersion;
-
- peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
- bufLen = peerKeyModulusLen + 4;
- #if RSA_CLIENT_KEY_ADD_LENGTH
- if(ctx->negProtocolVersion >= TLS_Version_1_0) {
- bufLen += 2;
- encodeLen = true;
- }
- #endif
- if (ERR(err = SSLAllocBuffer(&keyExchange->contents,
- bufLen,&ctx->sysCtx)) != 0)
- {
- return err;
- }
- dst = keyExchange->contents.data + 4;
- if(encodeLen) {
- dst += 2;
- }
- keyExchange->contents.data[0] = SSL_client_key_exchange;
-
- /* this is the record payload length */
- SSLEncodeInt(keyExchange->contents.data + 1, bufLen - 4, 3);
- if(encodeLen) {
- /* the length of the encrypted pre_master_secret */
- SSLEncodeInt(keyExchange->contents.data + 4,
- peerKeyModulusLen, 2);
- }
- err = sslRsaEncrypt(ctx,
- ctx->peerPubKey,
- /* FIXME - maybe this should be ctx->cspHand */
- ctx->peerPubKeyCsp,
- ctx->preMasterSecret.data,
- SSL_RSA_PREMASTER_SECRET_SIZE,
- dst,
- peerKeyModulusLen,
- &outputLen);
- if(err) {
- return err;
- }
-
- CASSERT(outputLen == encodeLen ?
- keyExchange->contents.length - 6 :
- keyExchange->contents.length - 4 );
-
- return SSLNoErr;
-}
-
-#if APPLE_DH
-static SSLErr
-SSLEncodeDHanonKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
-{ SSLErr err;
- unsigned int outputLen;
-
- if (ERR(err = SSLEncodeDHPremasterSecret(ctx)) != 0)
- return err;
-
- outputLen = ctx->dhExchangePublic.length + 2;
-
- keyExchange->contentType = SSL_handshake;
- assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
- (ctx->negProtocolVersion == TLS_Version_1_0));
- keyExchange->protocolVersion = ctx->negProtocolVersion;
-
- if (ERR(err = SSLAllocBuffer(&keyExchange->contents,outputLen + 4,&ctx->sysCtx)) != 0)
- return err;
-
- keyExchange->contents.data[0] = SSL_client_key_exchange;
- SSLEncodeInt(keyExchange->contents.data+1, ctx->dhExchangePublic.length+2, 3);
-
- SSLEncodeInt(keyExchange->contents.data+4, ctx->dhExchangePublic.length, 2);
- memcpy(keyExchange->contents.data+6, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
-
- return SSLNoErr;
-}
-#endif
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: nullciph.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: nullciph.c A dummy implementation of the null cipher
-
- The null cipher is used for SSL_NULL_WITH_NULL_NULL,
- SSL_RSA_WITH_NULL_MD5, and SSL_RSA_WITH_NULL_SHA ciphers.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#include <string.h>
-
-static SSLErr NullInit(
- uint8 *key,
- uint8* iv,
- CipherContext *cipherCtx,
- SSLContext *ctx);
-static SSLErr NullCrypt(
- SSLBuffer src,
- SSLBuffer dest,
- CipherContext *cipherCtx,
- SSLContext *ctx);
-static SSLErr NullFinish(
- CipherContext *cipherCtx,
- SSLContext *ctx);
-
-const SSLSymmetricCipher SSLCipherNull = {
- 0, /* Key size in bytes (ignoring parity) */
- 0, /* Secret key size */
- 0, /* IV size */
- 0, /* Block size */
- CSSM_ALGID_NONE,
- CSSM_ALGID_NONE,
- CSSM_ALGMODE_NONE,
- CSSM_PADDING_NONE,
- NullInit,
- NullCrypt,
- NullCrypt,
- NullFinish
-};
-
-static SSLErr NullInit(
- uint8 *key,
- uint8* iv,
- CipherContext *cipherCtx,
- SSLContext *ctx)
-{
- return SSLNoErr;
-}
-
-static SSLErr NullCrypt(
- SSLBuffer src,
- SSLBuffer dest,
- CipherContext *cipherCtx,
- SSLContext *ctx)
-{
- if (src.data != dest.data)
- memcpy(dest.data, src.data, src.length);
- return SSLNoErr;
-}
-
-static SSLErr NullFinish(
- CipherContext *cipherCtx,
- SSLContext *ctx)
-{
- return SSLNoErr;
-}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: SecureTransportPriv.h
+
+ Contains: Apple-private exported routines
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef _SECURE_TRANSPORT_PRIV_H_
+#define _SECURE_TRANSPORT_PRIV_H_ 1
+
+#include <Security/SecureTransport.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The size of of client- and server-generated random numbers in hello messages. */
+#define SSL_CLIENT_SRVR_RAND_SIZE 32
+
+/* The size of the pre-master and master secrets. */
+#define SSL_RSA_PREMASTER_SECRET_SIZE 48
+#define SSL_MASTER_SECRET_SIZE 48
+
+/*
+ * For the following three functions, *size is the available
+ * buffer size on entry and the actual size of the data returned
+ * on return. The above consts are for convenience.
+ */
+OSStatus SSLInternalMasterSecret(
+ SSLContextRef context,
+ void *secret, // mallocd by caller, SSL_MASTER_SECRET_SIZE
+ size_t *secretSize); // in/out
+
+OSStatus SSLInternalServerRandom(
+ SSLContextRef context,
+ void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
+ size_t *randSize); // in/out
+
+OSStatus SSLInternalClientRandom(
+ SSLContextRef context,
+ void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
+ size_t *randSize); // in/out
+
+OSStatus SSLInternal_PRF(
+ SSLContextRef context,
+ const void *secret,
+ size_t secretLen,
+ const void *label,
+ size_t labelLen,
+ const void *seed,
+ size_t seedLen,
+ void *out, // mallocd by caller, length >= outLen
+ size_t outLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SECURE_TRANSPORT_PRIV_H_ */
Contains: interface between SSL and CDSA
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
#include "ssl.h"
#include "sslPriv.h"
-#include "sslctx.h"
-#include "sslerrs.h"
+#include "sslContext.h"
#include <Security/cssmtype.h>
#ifdef __cplusplus
extern "C" {
#endif
-#if SSL_DEBUG
+#ifndef NDEBUG
extern void stPrintCdsaError(const char *op, CSSM_RETURN crtn);
extern char *stCssmErrToStr(CSSM_RETURN err);
#else
#define stPrintCdsaError(o, cr)
#endif
-extern SSLErr sslSetUpSymmKey(
+extern OSStatus sslSetUpSymmKey(
CSSM_KEY_PTR symKey,
CSSM_ALGORITHMS alg,
CSSM_KEYUSE keyUse, // CSSM_KEYUSE_ENCRYPT, etc.
uint8 *keyData,
uint32 keyDataLen); // in bytes
-extern SSLErr sslFreeKey(CSSM_CSP_HANDLE cspHand,
+extern OSStatus sslFreeKey(CSSM_CSP_HANDLE cspHand,
CSSM_KEY_PTR *key,
- #if ST_KEYCHAIN_ENABLE && ST_KC_KEYS_NEED_REF
+ #if ST_KC_KEYS_NEED_REF
SecKeychainRef *kcItem);
- #else /* !ST_KEYCHAIN_ENABLE */
+ #else /* !ST_KC_KEYS_NEED_REF */
void *kcItem);
- #endif /* ST_KEYCHAIN_ENABLE*/
+ #endif /* ST_KC_KEYS_NEED_REF*/
-extern SSLErr attachToCsp(SSLContext *ctx);
-extern SSLErr attachToCl(SSLContext *ctx);
-extern SSLErr attachToTp(SSLContext *ctx);
-extern SSLErr attachToAll(SSLContext *ctx);
-extern SSLErr detachFromAll(SSLContext *ctx);
+extern OSStatus attachToCsp(SSLContext *ctx);
+extern OSStatus attachToCl(SSLContext *ctx);
+extern OSStatus attachToTp(SSLContext *ctx);
+extern OSStatus attachToAll(SSLContext *ctx);
+extern OSStatus detachFromAll(SSLContext *ctx);
extern CSSM_DATA_PTR stMallocCssmData(uint32 size);
extern void stFreeCssmData(CSSM_DATA_PTR data, CSSM_BOOL freeStruct);
-extern SSLErr stSetUpCssmData(CSSM_DATA_PTR data, uint32 length);
+extern OSStatus stSetUpCssmData(CSSM_DATA_PTR data, uint32 length);
-/*
- * Common RNG function; replaces SSLRef's SSLRandomFunc
- */
-extern SSLErr sslRand(
- SSLContext *ctx,
- SSLBuffer *buf);
-
/*
* Given a DER-encoded cert, obtain its public key as a CSSM_KEY_PTR.
*/
-extern SSLErr sslPubKeyFromCert(
+extern OSStatus sslPubKeyFromCert(
SSLContext *ctx,
- const SSLBuffer *derCert,
+ const SSLBuffer &derCert,
CSSM_KEY_PTR *pubKey, // RETURNED
CSSM_CSP_HANDLE *cspHand); // RETURNED
/*
* Verify a cert chain.
*/
-extern SSLErr sslVerifyCertChain(
+extern OSStatus sslVerifyCertChain(
SSLContext *ctx,
- const SSLCertificate *certChain);
+ const SSLCertificate &certChain,
+ bool verifyHostName = true);
/*
* Raw RSA sign/verify.
*/
-SSLErr sslRsaRawSign(
+OSStatus sslRsaRawSign(
SSLContext *ctx,
const CSSM_KEY *privKey,
CSSM_CSP_HANDLE cspHand,
UInt32 sigLen, // available
UInt32 *actualBytes); // RETURNED
-SSLErr sslRsaRawVerify(
+OSStatus sslRsaRawVerify(
SSLContext *ctx,
const CSSM_KEY *pubKey,
CSSM_CSP_HANDLE cspHand,
/*
* Encrypt/Decrypt
*/
-SSLErr sslRsaEncrypt(
+OSStatus sslRsaEncrypt(
SSLContext *ctx,
const CSSM_KEY *pubKey,
CSSM_CSP_HANDLE cspHand,
UInt8 *cipherText, // mallocd by caller; RETURNED
UInt32 cipherTextLen, // available
UInt32 *actualBytes); // RETURNED
-SSLErr sslRsaDecrypt(
+OSStatus sslRsaDecrypt(
SSLContext *ctx,
const CSSM_KEY *privKey,
CSSM_CSP_HANDLE cspHand,
/*
* Get raw key bits from an RSA public key.
*/
-SSLErr sslGetPubKeyBits(
+OSStatus sslGetPubKeyBits(
SSLContext *ctx,
const CSSM_KEY *pubKey,
CSSM_CSP_HANDLE cspHand,
* Given raw RSA key bits, cook up a CSSM_KEY_PTR. Used in
* Server-initiated key exchange.
*/
-SSLErr sslGetPubKeyFromBits(
+OSStatus sslGetPubKeyFromBits(
SSLContext *ctx,
const SSLBuffer *modulus,
const SSLBuffer *exponent,
CSSM_KEY_PTR *pubKey, // mallocd and RETURNED
CSSM_CSP_HANDLE *cspHand); // RETURNED
-/*
- * Given two certs, verify subjectCert with issuerCert. Returns
- * CSSM_TRUE on successful verify.
- * Only special case on error is "subject cert expired", indicated by
- * *subjectExpired returned as CSSM_TRUE.
- */
-#if 0
-/* no longer needed */
-CSSM_BOOL sslVerifyCert(
- SSLContext *ctx,
- const CSSM_DATA_PTR subjectCert,
- const CSSM_DATA_PTR issuerCert,
- CSSM_CSP_HANDLE cspHand, // can verify with issuerCert
- CSSM_BOOL *subjectExpired); // RETURNED
-#endif
-
/*
* Given a DER-encoded cert, obtain its DER-encoded subject name.
*/
-#if ST_KEYCHAIN_ENABLE
CSSM_DATA_PTR sslGetCertSubjectName(
SSLContext *ctx,
const CSSM_DATA_PTR cert);
-#endif ST_KEYCHAIN_ENABLE
-#if (SSL_DEBUG && ST_KEYCHAIN_ENABLE)
+#if SSL_DEBUG
void verifyTrustedRoots(SSLContext *ctx,
CSSM_DATA_PTR certs,
unsigned numCerts);
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: appleGlue.h
-
- Contains: Glue layer between Apple SecureTransport and
- original SSLRef code.
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-#ifndef _SSL_H_
-#include "ssl.h"
-#endif
-
-#ifndef _APPLE_GLUE_H_
-#define _APPLE_GLUE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Functions to allow old code to use SSLBuffer-based I/O calls.
- * We redirect the calls here to an SSLIOFunc.
- * This is of course way inefficient due to an extra copy for
- * each I/O, but let's do it this way until the port settles down.
- */
-
-SSLErr sslIoRead(
- SSLBuffer buf,
- UInt32 *actualLength,
- SSLContext *ctx);
-
-SSLErr sslIoWrite(
- SSLBuffer buf,
- UInt32 *actualLength,
- SSLContext *ctx);
-
- /*
- * Convert between SSLErr and OSStatus.
- */
-extern SSLErr sslErrFromOsStatus(OSStatus o);
-extern OSStatus sslErrToOsStatus(SSLErr s);
-
-/*
- * Time functions - replaces SSLRef's SSLTimeFunc, SSLConvertTimeFunc
- */
-extern SSLErr sslTime(UInt32 *time);
-SSLErr sslConvertTime(UInt32 *time);
-
-#ifdef __cplusplus
-}
-#endif
-
- #endif /* _APPLE_GLUE_H_ */
-
-
\ No newline at end of file
Contains: Session storage module, Apple CDSA version.
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
*/
-/*
- * This file replaces the caller-specified SSLAddSessionFunc,
- * SSLGetSessionFunc, and SSLDeleteSessionFunc callbacks in the
- * original SSLRef 3.0.
- */
-
#ifndef _APPLE_SESSION_H_
#define _APPLE_SESSION_H_
-#ifndef _SSL_H_
#include "ssl.h"
-#endif
#ifdef __cplusplus
extern "C" {
#endif
-extern SSLErr sslAddSession (
+extern OSStatus sslAddSession (
const SSLBuffer sessionKey,
const SSLBuffer sessionData);
-extern SSLErr sslGetSession (
+extern OSStatus sslGetSession (
const SSLBuffer sessionKey,
SSLBuffer *sessionData);
-extern SSLErr sslDeleteSession (
+extern OSStatus sslDeleteSession (
const SSLBuffer sessionKey);
-extern SSLErr sslCleanupSession();
+extern OSStatus sslCleanupSession();
#ifdef __cplusplus
}
Contains: SSLCipherSpec declarations
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
#ifndef _CIPHER_SPECS_H_
#define _CIPHER_SPECS_H_
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _CRYPTTYPE_H_
+#include "sslContext.h"
#include "cryptType.h"
+
+#ifdef __cplusplus
+extern "C" {
#endif
/*
* Build ctx->validCipherSpecs as a copy of all known CipherSpecs.
*/
-extern SSLErr sslBuildCipherSpecArray(SSLContext *ctx);
+extern OSStatus sslBuildCipherSpecArray(SSLContext *ctx);
/*
* Given a valid ctx->selectedCipher and ctx->validCipherSpecs, set
* ctx->selectedCipherSpec as appropriate.
*/
-SSLErr FindCipherSpec(SSLContext *ctx);
+OSStatus FindCipherSpec(SSLContext *ctx);
extern const SSLCipherSpec SSL_NULL_WITH_NULL_NULL_CipherSpec;
+#ifdef __cplusplus
+}
+#endif
#endif /* _CIPHER_SPECS_H_ */
Contains: Crypto structures and routines
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
*/
-/* *********************************************************************
- File: cryptype.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: cryptype.h Crypto structures and routines
-
- Types associated with cryptographic functionality, including hashes,
- symmetric ciphers, and cipher specs.
-
- ****************************************************************** */
#ifndef _CRYPTTYPE_H_
#define _CRYPTTYPE_H_ 1
-#include "sslerrs.h"
#include <Security/CipherSuite.h>
#include "sslPriv.h"
-#include "sslctx.h"
+#include "sslContext.h"
#include "tls_hmac.h"
#ifdef __cplusplus
SSLCipherSuite cipherSuite;
} SSLCipherMapping;
-typedef SSLErr (*HashInit)(SSLBuffer digestCtx, SSLContext *sslCtx);
-typedef SSLErr (*HashUpdate)(SSLBuffer digestCtx, SSLBuffer data);
+typedef OSStatus (*HashInit)(SSLBuffer &digestCtx, SSLContext *sslCtx);
+typedef OSStatus (*HashUpdate)(SSLBuffer &digestCtx, const SSLBuffer &data);
/* HashFinal also does HashClose */
-typedef SSLErr (*HashFinal)(SSLBuffer digestCtx, SSLBuffer digest);
-typedef SSLErr (*HashClose)(SSLBuffer digestCtx, SSLContext *sslCtx);
-typedef SSLErr (*HashClone)(SSLBuffer src, SSLBuffer dest);
+typedef OSStatus (*HashFinal)(SSLBuffer &digestCtx, SSLBuffer &digest);
+typedef OSStatus (*HashClose)(SSLBuffer &digestCtx, SSLContext *sslCtx);
+typedef OSStatus (*HashClone)(const SSLBuffer &src, SSLBuffer &dest);
typedef struct
{ UInt32 contextSize;
UInt32 digestSize;
} HashReference;
/*
- * TLS extension:
- * -- new struct HashHmacReference
- * -- structs which used to use HashReference now use HashHmacReference
- * -- new union HashHmacContext, used in CipherContext.
+ * TLS addenda:
+ * -- new struct HashHmacReference
+ * -- structs which used to use HashReference now use HashHmacReference
+ * -- new union HashHmacContext, used in CipherContext.
*/
typedef struct {
const HashReference *hash;
struct _SslTlsCallouts;
/*
- * All symmetric ciphers go thru CDSA, but we'll keep these callouts for
- * now. The major change here from SSLRef3 is the inclusion of the CipherContext
- * arg, for alg/mode and key storage.
+ * All symmetric ciphers go thru CDSA, via these callouts.
*/
struct CipherContext;
typedef struct CipherContext CipherContext;
-typedef SSLErr (*SSLKeyFunc)(
+typedef OSStatus (*SSLKeyFunc)(
UInt8 *key,
UInt8 *iv,
CipherContext *cipherCtx,
SSLContext *ctx);
-typedef SSLErr (*SSLCryptFunc)(
+typedef OSStatus (*SSLCryptFunc)(
SSLBuffer src,
SSLBuffer dest,
CipherContext *cipherCtx,
SSLContext *ctx);
-typedef SSLErr (*SSLFinishFunc)(
+typedef OSStatus (*SSLFinishFunc)(
CipherContext *cipherCtx,
SSLContext *ctx);
SSLFinishFunc finish;
} SSLSymmetricCipher;
-#define MAX_DIGEST_SIZE 20 /* SHA digest size = 160 bits */
-#define MAX_MAC_PADDING 48 /* MD5 MAC padding size = 48 bytes */
-#define MASTER_SECRET_LEN 48 /* master secret = 3 x MD5 hashes concatenated */
+#define MAX_MAC_PADDING 48 /* MD5 MAC padding size = 48 bytes */
+#define MASTER_SECRET_LEN 48 /* master secret = 3 x MD5 hashes concatenated */
/* SSL V2 - mac secret is the size of symmetric key, not digest */
#define MAX_SYMKEY_SIZE 24
typedef enum
{ SSL_NULL_auth,
- /*
- * FIXME: I have no idea what the difference is between
- * e.g. SSL_RSA and SS_RSA_EXPORT. These don't go over the
- * wire.
- * The few times the SSLRef code behaves differently between
- * these two look wrong. See SSLDecodeRSAKeyExchange(),
- * SSLAdvanceHandshake().
- *
- * UPDATE: see comments for SSL_SERVER_KEYEXCH_HACK hack.
- */
SSL_RSA,
SSL_RSA_EXPORT,
SSL_DH_DSS,
} SSLCipherSpec;
extern const SSLCipherMapping SSL2CipherMap[];
-extern const int SSL2CipherMapCount;
-extern UInt8 SSLMACPad1[], SSLMACPad2[];
+extern const unsigned SSL2CipherMapCount;
#ifdef __cplusplus
}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: digests.h
-
- Contains: HashReference declarations
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-#ifndef _DIGESTS_H_
-#define _DIGESTS_H_ 1
-
-#include "cryptType.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * These numbers show up all over the place...might as well hard code 'em once.
- */
-#define SSL_MD5_DIGEST_LEN 16
-#define SSL_SHA1_DIGEST_LEN 20
-#define SSL_MAX_DIGEST_LEN 20
-
-extern const HashReference SSLHashNull;
-extern const HashReference SSLHashMD5;
-extern const HashReference SSLHashSHA1;
-
-extern void SSLInitMACPads(void);
-extern SSLErr CloneHashState(
- const HashReference *ref,
- SSLBuffer state,
- SSLBuffer *newState,
- SSLContext *ctx);
-extern SSLErr ReadyHash(
- const HashReference *ref,
- SSLBuffer *state,
- SSLContext *ctx);
-extern SSLErr CloseHash(
- const HashReference *ref,
- SSLBuffer *state,
- SSLContext *ctx);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DIGESTS_H_ */
/*
File: ssl.h
- Contains: convenience header, including public and private parts
- of original ssl.h
+ Contains: convenience header
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
*/
-#ifndef _SSL_H_
-#define _SSL_H_
+#ifndef _SSL_SSL_H_
+#define _SSL_SSL_H_
#include <Security/SecureTransport.h>
#include "sslPriv.h"
-#endif /* _SSL_H */
\ No newline at end of file
+/* and this system-wide kludge */
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#endif /* _SSL_SSL_H_ */
/*
File: ssl2.h
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
*/
-/* *********************************************************************
- File: ssl2.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ssl2.h SSL 2 functionality header
-
- This file contains function prototypes and equate values for SSL2.
- The relevant functions are contained in files whose names match
- ssl2*.c
-
- ****************************************************************** */
#ifndef _SSL2_H_
#define _SSL2_H_
-#ifndef _SECURE_TRANSPORT_H_
#include "SecureTransport.h"
-#endif
-
-#ifndef _SSL_PRIV_H_
#include "sslPriv.h"
-#endif
+#include "sslRecord.h"
-#ifndef _SSLREC_H_
-#include "sslrec.h"
+#ifdef __cplusplus
+extern "C" {
#endif
-typedef enum
-{ ssl2_mt_error = 0,
- ssl2_mt_client_hello = 1,
- ssl2_mt_client_master_key = 2,
- ssl2_mt_client_finished = 3,
- ssl2_mt_server_hello = 4,
- ssl2_mt_server_verify = 5,
- ssl2_mt_server_finished = 6,
- ssl2_mt_request_certificate = 7,
- ssl2_mt_client_certificate = 8,
- ssl2_mt_kickstart_handshake = 99
+typedef enum {
+ SSL2_MsgError = 0,
+ SSL2_MsgClientHello = 1,
+ SSL2_MsgClientMasterKey = 2,
+ SSL2_MsgClientFinished = 3,
+ SSL2_MsgServerHello = 4,
+ SSL2_MsgServerVerify = 5,
+ SSL2_MsgServerFinished = 6,
+ SSL2_MsgRequestCert = 7,
+ SSL2_MsgClientCert = 8,
+ SSL2_MsgKickstart = 99
} SSL2MessageType;
-typedef enum
-{ ssl2_pe_no_cipher = 1,
- ssl2_pe_no_certificate = 2,
- ssl2_pe_bad_certificate = 4,
- ssl2_pe_unsupported_certificate_type = 6
+typedef enum {
+ SSL2_ErrNoCipher = 1,
+ SSL2_ErrNoCert = 2,
+ SSL2_ErrBadCert = 4,
+ SSL2_ErrUnsupportedCert = 6
} SSL2ErrorCode;
-typedef enum
-{ ssl2_ct_x509_certificate = 1
+typedef enum{
+ SSL2_CertTypeX509 = 1
} SSL2CertTypeCode;
#define SSL2_CONNECTION_ID_LENGTH 16
-typedef SSLErr (*EncodeSSL2MessageFunc)(SSLBuffer *msg, SSLContext *ctx);
-SSLErr SSL2ReadRecord(SSLRecord *rec, SSLContext *ctx);
-SSLErr SSL2WriteRecord(SSLRecord rec, SSLContext *ctx);
-SSLErr SSL2ProcessMessage(SSLRecord rec, SSLContext *ctx);
-SSLErr SSL2SendError(SSL2ErrorCode error, SSLContext *ctx);
-SSLErr SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx);
-SSLErr SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx);
-SSLErr SSL2CompareSessionIDs(SSLContext *ctx);
-SSLErr SSL2InstallSessionKey(SSLContext *ctx);
-SSLErr SSL2GenerateSessionID(SSLContext *ctx);
-SSLErr SSL2InitCiphers(SSLContext *ctx);
-
-SSLErr SSL2ProcessClientHello(SSLBuffer msgContents, SSLContext *ctx);
-SSLErr SSL2EncodeClientHello(SSLBuffer *msg, SSLContext *ctx);
-SSLErr SSL2ProcessClientMasterKey(SSLBuffer msgContents, SSLContext *ctx);
-SSLErr SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx);
-SSLErr SSL2ProcessClientFinished(SSLBuffer msgContents, SSLContext *ctx);
-SSLErr SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx);
-SSLErr SSL2ProcessServerHello(SSLBuffer msgContents, SSLContext *ctx);
-SSLErr SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx);
-SSLErr SSL2ProcessServerVerify(SSLBuffer msgContents, SSLContext *ctx);
-SSLErr SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx);
-SSLErr SSL2ProcessServerFinished(SSLBuffer msgContents, SSLContext *ctx);
-SSLErr SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx);
+typedef OSStatus (*EncodeSSL2MessageFunc)(SSLBuffer &msg, SSLContext *ctx);
+OSStatus SSL2ReadRecord(SSLRecord &rec, SSLContext *ctx);
+OSStatus SSL2WriteRecord(SSLRecord &rec, SSLContext *ctx);
+OSStatus SSL2ProcessMessage(SSLRecord &rec, SSLContext *ctx);
+OSStatus SSL2SendError(SSL2ErrorCode error, SSLContext *ctx);
+OSStatus SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx);
+OSStatus SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx);
+OSStatus SSL2CompareSessionIDs(SSLContext *ctx);
+OSStatus SSL2InstallSessionKey(SSLContext *ctx);
+OSStatus SSL2GenerateSessionID(SSLContext *ctx);
+OSStatus SSL2InitCiphers(SSLContext *ctx);
+
+OSStatus SSL2ProcessClientHello(SSLBuffer msgContents, SSLContext *ctx);
+OSStatus SSL2EncodeClientHello(SSLBuffer &msg, SSLContext *ctx);
+OSStatus SSL2ProcessClientMasterKey(SSLBuffer msgContents, SSLContext *ctx);
+OSStatus SSL2EncodeClientMasterKey(SSLBuffer &msg, SSLContext *ctx);
+OSStatus SSL2ProcessClientFinished(SSLBuffer msgContents, SSLContext *ctx);
+OSStatus SSL2EncodeClientFinished(SSLBuffer &msg, SSLContext *ctx);
+OSStatus SSL2ProcessServerHello(SSLBuffer msgContents, SSLContext *ctx);
+OSStatus SSL2EncodeServerHello(SSLBuffer &msg, SSLContext *ctx);
+OSStatus SSL2ProcessServerVerify(SSLBuffer msgContents, SSLContext *ctx);
+OSStatus SSL2EncodeServerVerify(SSLBuffer &msg, SSLContext *ctx);
+OSStatus SSL2ProcessServerFinished(SSLBuffer msgContents, SSLContext *ctx);
+OSStatus SSL2EncodeServerFinished(SSLBuffer &msg, SSLContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
#endif
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/* *********************************************************************
+ File: sslAlertMessage.h
+ ****************************************************************** */
+
+#ifndef _SSLALERTMESSAGE_H_
+#define _SSLALERTMESSAGE_H_ 1
+
+#ifndef _SECURE_TRANSPORT_H_
+#include "SecureTransport.h"
+#endif
+
+#include "sslPriv.h"
+#include "sslRecord.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{ SSL_AlertLevelWarning = 1,
+ SSL_AlertLevelFatal = 2
+} AlertLevel;
+
+typedef enum
+{ SSL_AlertCloseNotify = 0,
+ SSL_AlertUnexpectedMsg = 10,
+ SSL_AlertBadRecordMac = 20,
+ SSL_AlertDecryptionFail = 21, /* TLS */
+ SSL_AlertRecordOverflow = 22, /* TLS */
+ SSL_AlertDecompressFail = 30,
+ SSL_AlertHandshakeFail = 40,
+ SSL_AlertNoCert = 41,
+ SSL_AlertBadCert = 42, /* SSLv3 only */
+ SSL_AlertUnsupportedCert = 43,
+ SSL_AlertCertRevoked = 44,
+ SSL_AlertCertExpired = 45,
+ SSL_AlertCertUnknown = 46,
+ SSL_AlertIllegalParam = 47,
+ /* remainder are TLS addenda */
+ SSL_AlertUnknownCA = 48,
+ SSL_AlertAccessDenied = 49,
+ SSL_AlertDecodeError = 50,
+ SSL_AlertDecryptError = 51,
+ SSL_AlertExportRestriction = 60,
+ SSL_AlertProtocolVersion = 70,
+ SSL_AlertInsufficientSecurity = 71,
+ SSL_AlertInternalError = 80,
+ SSL_AlertUserCancelled = 90,
+ SSL_AlertNoRenegotiation = 100
+} AlertDescription;
+
+OSStatus SSLProcessAlert(
+ SSLRecord rec,
+ SSLContext *ctx);
+OSStatus SSLSendAlert(
+ AlertLevel level,
+ AlertDescription desc,
+ SSLContext *ctx);
+OSStatus SSLEncodeAlert(
+ SSLRecord &rec,
+ AlertLevel level,
+ AlertDescription desc,
+ SSLContext *ctx);
+OSStatus SSLFatalSessionAlert(
+ AlertDescription desc,
+ SSLContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSLALERTMESSAGE_H_ */
* publicExponent INTEGER -- e }
*/
-SSLErr sslDecodeRsaBlob(
+OSStatus sslDecodeRsaBlob(
const SSLBuffer *blob, /* PKCS-1 encoded */
SSLBuffer *modulus, /* data mallocd and RETURNED */
SSLBuffer *exponent); /* data mallocd and RETURNED */
* BER-encoded RSA public key blob.
*/
-SSLErr sslEncodeRsaBlob(
+OSStatus sslEncodeRsaBlob(
const SSLBuffer *modulus,
const SSLBuffer *exponent,
SSLBuffer *blob); /* data mallocd and RETURNED */
* general Keychain functionality.
*/
-#define ST_KEYCHAIN_ENABLE 1
-
/*
* Work around the Netscape Server Key Exchange bug. When this is
* true, only do server key exchange if both of the following are
* -- an export-grade ciphersuite has been negotiated, and
* -- an encryptPrivKey is present in the context
*/
-#define SSL_SERVER_KEYEXCH_HACK 0
+#define SSL_SERVER_KEYEXCH_HACK 0
/*
* RSA functions which use a public key to do encryption force
* might not be enough - what if server certs don't have the
* appropriate usage bits?
*/
-#define RSA_PUB_KEY_USAGE_HACK 1
-
-/*
- * For now, we're assuming that the domestic CSP is available - major
- * rework needed if it's not.
- */
-#define APPLE_DOMESTIC_CSP_REQUIRED 1
+#define RSA_PUB_KEY_USAGE_HACK 1
/*
* CSSM_KEYs obtained from Keychain require a SecKeychainRef to be freed/released.
*/
#define ST_KC_KEYS_NEED_REF 0
-/*
- * Initial bringup of server/keychain on X: the certRefs argument of
- * SSLSetCertificate() contains one DLDBHandle, not a number of
- * SecIdentityRefs. The DLDB contains exactly one private key, and a
- * cert with PrintName which matches that key. Public key is obtained
- * from the cert. We have to manually attach to the CSPDL in this case.
- */
-#define ST_FAKE_KEYCHAIN 0
-
-/*
- * Flags need for manually attaching to CSPDL for configuration which
- * does not contain a working SecKeychainGetCSPHandle().
- */
-#define ST_FAKE_GET_CSPDL_HANDLE 0
-
/*
* We manage trusted certs and pass them to the TP.
* -- OS 9 - true
/* debugging flags */
#ifdef NDEBUG
-#define SSL_DEBUG 0
-#define ERROR_LOG_ENABLE 0
+#define SSL_DEBUG 0
+#define ERROR_LOG_ENABLE 0
#else
-#define SSL_DEBUG 1
-#define ERROR_LOG_ENABLE 1
+#define SSL_DEBUG 1
+#define ERROR_LOG_ENABLE 1
#endif /* NDEBUG */
#if defined(__cplusplus)
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslContext.h
+
+ Contains: Private SSL typedefs: SSLContext and its components
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef _SSLCONTEXT_H_
+#define _SSLCONTEXT_H_ 1
+
+#include <Security/SecureTransport.h>
+#include "sslBuildFlags.h"
+#include <Security/cssmtype.h>
+
+#include "sslPriv.h"
+#include "tls_ssl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{ SSLReadFunc read;
+ SSLWriteFunc write;
+ SSLConnectionRef ioRef;
+} IOContext;
+
+/*
+ * An element in a certificate chain.
+ */
+typedef struct SSLCertificate
+{
+ struct SSLCertificate *next;
+ SSLBuffer derCert;
+} SSLCertificate;
+
+#include "cryptType.h"
+
+/*
+ * An SSLContext contains four of these - one for each of {read,write} and for
+ * {current, pending}.
+ */
+struct CipherContext
+{
+
+ const HashHmacReference *macRef; /* HMAC (TLS) or digest (SSL) */
+ const SSLSymmetricCipher *symCipher;
+
+ /* this is a context which is reused once per record */
+ HashHmacContext macCtx;
+
+ /*
+ * symKey is obtained from the CSP at cspHand. Normally this
+ * cspHand is the same as ctx->cspHand; some day they might differ.
+ * Code which deals with this struct doesn't ever have to
+ * attach or detach from cspHand - that's taken care of at the
+ * SSLContext level.
+ */
+ CSSM_KEY_PTR symKey;
+ CSSM_CSP_HANDLE cspHand;
+ CSSM_CC_HANDLE ccHand;
+
+ /* needed in CDSASymmInit */
+ uint8 encrypting;
+
+ sslUint64 sequenceNum;
+ uint8 ready;
+
+ /* in SSL2 mode, the macSecret is the same size as the
+ * cipher key - which is 24 bytes in the 3DES case. */
+ uint8 macSecret[MAX_SYMKEY_SIZE];
+};
+/* typedef in cryptType.h */
+
+#include "sslHandshake.h"
+
+typedef struct WaitingRecord
+{ struct WaitingRecord *next;
+ SSLBuffer data;
+ uint32 sent;
+} WaitingRecord;
+
+typedef struct DNListElem
+{ struct DNListElem *next;
+ SSLBuffer derDN;
+} DNListElem;
+
+struct SSLContext
+{
+ IOContext ioCtx;
+
+ /*
+ * For the first two, SSL_Version_Undetermined means "get the best we
+ * can, up to macProtocolVersion".
+ */
+ SSLProtocolVersion reqProtocolVersion; /* requested by app */
+ SSLProtocolVersion negProtocolVersion; /* negotiated */
+ SSLProtocolVersion maxProtocolVersion; /* max allowed by app */
+ SSLProtocolSide protocolSide;
+ const struct _SslTlsCallouts *sslTslCalls; /* selects between SSLv3 and TLSv1 */
+
+ /* crypto state in CDSA-centric terms */
+
+ CSSM_KEY_PTR signingPrivKey;/* our private signing key */
+ CSSM_KEY_PTR signingPubKey; /* our public signing key */
+ CSSM_CSP_HANDLE signingKeyCsp; /* associated DL/CSP */
+ #if ST_KC_KEYS_NEED_REF
+ SecKeychainRef signingKeyRef; /* for signingPrivKey */
+ #else
+ void *signingKeyRef; /* TBD */
+ #endif /* ST_KC_KEYS_NEED_REF */
+
+ CSSM_KEY_PTR encryptPrivKey;/* our private encrypt key, for
+ * server-initiated key exchange */
+ CSSM_KEY_PTR encryptPubKey; /* public version of above */
+ CSSM_CSP_HANDLE encryptKeyCsp;
+ #if ST_KC_KEYS_NEED_REF
+ SecKeychainRef encryptKeyRef; /* for signingPrivKey */
+ #else
+ void *encryptKeyRef; /* TBD */
+ #endif /* ST_KC_KEYS_NEED_REF */
+
+ CSSM_KEY_PTR peerPubKey;
+ CSSM_CSP_HANDLE peerPubKeyCsp; /* may not be needed, we figure this
+ * one out by trial&error, right? */
+
+ /*
+ * Various cert chains.
+ * For all three, the root is the first in the chain.
+ */
+ SSLCertificate *localCert;
+ SSLCertificate *encryptCert;
+ SSLCertificate *peerCert;
+
+ /*
+ * trusted root certs; specific to this implementation, we'll store
+ * them conveniently...these will be used as AnchorCerts in a TP
+ * call.
+ */
+ uint32 numTrustedCerts;
+ CSSM_DATA_PTR trustedCerts;
+
+ /*
+ * Keychain to which newly encountered root certs are attempted
+ * to be added. AccessCreds untyped for now.
+ */
+ #if ST_MANAGES_TRUSTED_ROOTS
+ SecKeychainRef newRootCertKc;
+ void *accessCreds;
+ #endif /* ST_MANAGES_TRUSTED_ROOTS */
+
+ /* for symmetric cipher and RNG */
+ CSSM_CSP_HANDLE cspHand;
+
+ /* session-wide handles for Apple TP, CL */
+ CSSM_TP_HANDLE tpHand;
+ CSSM_CL_HANDLE clHand;
+
+ /* FIXME - how will we represent this? */
+ void *dhAnonParams;
+ void *peerDHParams;
+
+ Boolean allowExpiredCerts;
+ Boolean allowExpiredRoots;
+ Boolean enableCertVerify;
+
+ SSLBuffer sessionID;
+
+ SSLBuffer dhPeerPublic;
+ SSLBuffer dhExchangePublic;
+ SSLBuffer dhPrivate;
+
+ SSLBuffer peerID;
+ SSLBuffer resumableSession;
+
+ char *peerDomainName;
+ UInt32 peerDomainNameLen;
+
+ CipherContext readCipher;
+ CipherContext writeCipher;
+ CipherContext readPending;
+ CipherContext writePending;
+
+ uint16 selectedCipher; /* currently selected */
+ const SSLCipherSpec *selectedCipherSpec; /* ditto */
+ SSLCipherSpec *validCipherSpecs; /* context's valid specs */
+ unsigned numValidCipherSpecs; /* size of validCipherSpecs */
+ SSLHandshakeState state;
+
+ /* server-side only */
+ SSLAuthenticate clientAuth; /* kNeverAuthenticate, etc. */
+ Boolean tryClientAuth;
+
+ /* client and server */
+ SSLClientCertificateState clientCertState;
+
+ DNListElem *acceptableDNList;
+
+ int certRequested;
+ int certSent;
+ int certReceived;
+ int x509Requested;
+
+ uint8 clientRandom[SSL_CLIENT_SRVR_RAND_SIZE];
+ uint8 serverRandom[SSL_CLIENT_SRVR_RAND_SIZE];
+ SSLBuffer preMasterSecret;
+ uint8 masterSecret[SSL_MASTER_SECRET_SIZE];
+
+ /* running digests of all handshake messages */
+ SSLBuffer shaState, md5State;
+
+ SSLBuffer fragmentedMessageCache;
+
+ unsigned ssl2ChallengeLength;
+ unsigned ssl2ConnectionIDLength;
+ unsigned ssl2SessionMatch;
+
+ /* Record layer fields */
+ SSLBuffer partialReadBuffer;
+ uint32 amountRead;
+
+ /* Transport layer fields */
+ WaitingRecord *recordWriteQueue;
+ SSLBuffer receivedDataBuffer;
+ uint32 receivedDataPos;
+
+ Boolean allowAnyRoot; // don't require known roots
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSLCONTEXT_H_ */
Written by: Doug Mitchell
Copyright: (c) 1998, 1999 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- 03/10/98 dpm Created.
-
*/
#ifndef _SSL_DEBUG_H_
#define _SSL_DEBUG_H_
-#include "sslBuildFlags.h"
-
-#if SSL_DEBUG || ERROR_LOG_ENABLE
-
-/* any other way? */
-#define LOG_VIA_PRINTF 1
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#if !LOG_VIA_PRINTF
-
-#error Hey, figure out a debug mechanism
-
-#include <string.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
-#include <TextUtils.h>
-
-/* common log macros */
-
-/* remaining ones can take constant strings */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void dblog0(char *str);
-extern void dblog1(char *str, void * arg1);
-extern void dblog2(char *str, void * arg1, void * arg2);
-extern void dblog3(char *str, void * arg1, void * arg2, void * arg3);
-extern void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#else /* LOG_VIA_PRINTF */
-
-#define dblog0(str) printf(str)
-#define dblog1(str, arg1) printf(str, arg1)
-#define dblog2(str, arg1, arg2) printf(str, arg1, arg2)
-#define dblog3(str, arg1, arg2, arg3) printf(str, arg1, arg2, arg3)
-#define dblog4(str, arg1, arg2, arg3, arg4) printf(str, arg1, arg2, arg3, arg4)
-
-#endif /* LOG_VIA_PRINTF */
-
-#else /* log macros disabled */
-
-#define dblog0(str)
-#define dblog1(str, arg1)
-#define dblog2(str, arg1, arg2)
-#define dblog3(str, arg1, arg2, arg3)
-#define dblog4(str, arg1, arg2, arg3, arg4)
-
-#endif /* SSL_DEBUG || ERROR_LOG_ENABLE */
-
-#if SSL_DEBUG
-
-#define dprintf0(str) dblog0(str)
-#define dprintf1(str, arg1) dblog1(str, arg1)
-#define dprintf2(str, arg1, arg2) dblog2(str, arg1, arg2)
-#define dprintf3(str, arg1, arg2, arg3) dblog3(str, arg1, arg2, arg3)
-#define dprintf4(str, arg1, arg2, arg3, arg4) dblog4(str, arg1, arg2, arg3, arg4)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static inline volatile void sslPanic(const char *str)
-{
- printf(str);
- exit(1);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#define CASSERT(expression) \
- ((expression) ? (void)0 : \
- (dprintf1 ("Assertion failed: " #expression \
- ", file " __FILE__ ", line %d.\n", __LINE__), \
- sslPanic("Assertion Failure")))
-
-#else /* SSL_DEBUG */
-
-#define dprintf0(str)
-#define dprintf1(str, arg1)
-#define dprintf2(str, arg1, arg2)
-#define dprintf3(str, arg1, arg2, arg3)
-#define dprintf4(str, arg1, arg2, arg3, arg4)
-
-#define CASSERT(expression)
-#define sslPanic(s)
-#endif /* SSL_DEBUG */
-
-/*
- * Error logging. This may well be platform dependent.
- */
-#if ERROR_LOG_ENABLE
-#define errorLog0(str) dblog0(str);
-#define errorLog1(str, arg1) dblog1(str, arg1)
-#define errorLog2(str, arg1, arg2) dblog2(str, arg1, arg2)
-#define errorLog3(str, arg1, arg2, arg3) dblog3(str, arg1, arg2, arg3)
-#define errorLog4(str, arg1, arg2, arg3, arg4) dblog4(str, arg1, arg2, arg3, arg4)
-
-#else /* ERROR_LOG_ENABLE */
-
-#define errorLog0(str)
-#define errorLog1(str, arg1)
-#define errorLog2(str, arg1, arg2)
-#define errorLog3(str, arg1, arg2, arg3)
-#define errorLog4(str, arg1, arg2, arg3, arg4)
-
-#endif /* ERROR_LOG_ENABLE */
-
-/*
- * Override SSLRef macros
- */
-#define ERR(x) (x)
-#define DUMP_BUFFER_NAME(name, buf)
-#define DUMP_DATA_NAME(name, p, len)
-#define ASSERTMSG(m) sslPanic(m)
-#define DEBUGVAL1(str, arg) errorLog1(str, arg)
-
-/*** SSL-Specific debugging ***/
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-/* Logging Enable Flags */
-
-#if SSL_DEBUG
+#include "sslContext.h"
+#include <Security/debugging.h>
+#include <assert.h>
/* log changes in handshake state */
-#define LOG_HDSK_STATE 0
+#define sslHdskStateDebug(args...) debug("sslHdskState", ## args)
-/* log handshake messages */
-#define LOG_HDSK_MSG 0
+/* log handshake and alert messages */
+#define sslHdskMsgDebug(args...) debug("sslHdskMsg", ## args)
/* log negotiated handshake parameters */
-#define LOG_NEGOTIATE 0
+#define sslLogNegotiateDebug(args...) debug("sslLogNegotiate", ## args)
/* log received protocol messsages */
-#define LOG_RX_PROTOCOL 0
-
+#define sslLogRxProtocolDebug(msgType) debug("sslLogRxProtocol", \
+ "---received protoMsg %s", msgType)
+
/* log resumable session info */
-#define LOG_RESUM_SESSION 0
+#define sslLogResumSessDebug(args...) debug("sslResumSession", ## args)
-#else /* !SSL_DEBUG - normal build - all flags disabled */
-#define LOG_HDSK_STATE 0
-#define LOG_HDSK_MSG 0
-#define LOG_NEGOTIATE 0
-#define LOG_RX_PROTOCOL 0
-#define LOG_RESUM_SESSION 0
-#endif /* SSL_DEBUG */
+/* log low-level session info in appleSession.cpp */
+#define sslLogSessCacheDebug(args...) debug("sslSessionCache", ## args)
+
+/* log record-level I/O (SSLRead, SSLWrite) */
+#define sslLogRecordIo(args...) debug("sslRecordIo", ## args)
+
+#ifdef NDEBUG
-#if LOG_HDSK_STATE
-extern void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState);
-#else /* LOG_HDSK_STATE */
#define SSLChangeHdskState(ctx, newState) { ctx->state=newState; }
-#endif /* LOG_HDSK_STATE */
+#define SSLLogHdskMsg(msg, sent)
+
+/* all errors logged to stdout for DEBUG config only */
+#define sslErrorLog(args...)
+
+#else
+
+#include "sslAlertMessage.h"
-#if LOG_HDSK_MSG
extern void SSLLogHdskMsg(SSLHandshakeType msg, char sent);
extern char *hdskStateToStr(SSLHandshakeState state);
-#else /* LOG_HDSK_STATE */
-#define SSLLogHdskMsg(msg, sent)
-#endif /* LOG_HDSK_STATE */
+extern void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState);
-#if LOG_RESUM_SESSION
-#define SSLLogResumSess(m) printf(m)
-#else
-#define SSLLogResumSess(m)
-#endif /* LOG_RESUM_SESSION */
+/* all errors logged to stdout for DEBUG config only */
+#define sslErrorLog(args...) printf(args)
-/*
- * A crufty little routine to write cert blobs to disk.
- * Implemented in appleCdsa.c.
- */
-#if SSL_DEBUG
-extern void writeBufBlob(const SSLBuffer *blob,
- const char *fileName);
-#endif
+#endif /* NDEBUG */
#endif /* _SSL_DEBUG_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslDigests.h
+
+ Contains: HashReference declarations
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef _SSL_DIGESTS_H_
+#define _SSL_DIGESTS_H_ 1
+
+#include "cryptType.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * These numbers show up all over the place...might as well hard code 'em once.
+ */
+#define SSL_MD5_DIGEST_LEN 16
+#define SSL_SHA1_DIGEST_LEN 20
+#define SSL_MAX_DIGEST_LEN 20
+
+extern const UInt8 SSLMACPad1[], SSLMACPad2[];
+
+extern const HashReference SSLHashNull;
+extern const HashReference SSLHashMD5;
+extern const HashReference SSLHashSHA1;
+
+extern OSStatus CloneHashState(
+ const HashReference &ref,
+ const SSLBuffer &state,
+ SSLBuffer &newState,
+ SSLContext *ctx);
+extern OSStatus ReadyHash(
+ const HashReference &ref,
+ SSLBuffer &state,
+ SSLContext *ctx);
+extern OSStatus CloseHash(
+ const HashReference &ref,
+ SSLBuffer &state,
+ SSLContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSL_DIGESTS_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/* *********************************************************************
+ File: sslHandshake.h - SSL Handshake Layer
+ ****************************************************************** */
+
+#ifndef _SSLHANDSHAKE_H_
+#define _SSLHANDSHAKE_H_
+
+#include "cryptType.h"
+#include "sslRecord.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{ SSL_HdskHelloRequest = 0,
+ SSL_HdskClientHello = 1,
+ SSL_HdskServerHello = 2,
+ SSL_HdskCert = 11,
+ SSL_HdskServerKeyExchange = 12,
+ SSL_HdskCertRequest = 13,
+ SSL_HdskServerHelloDone = 14,
+ SSL_HdskCertVerify = 15,
+ SSL_HdskClientKeyExchange = 16,
+ SSL_HdskFinished = 20,
+ SSL_HdskNoCertAlert = 100
+} SSLHandshakeType;
+
+typedef enum
+{ SSL_read,
+ SSL_write
+} CipherSide;
+
+typedef enum
+{
+ SSL_HdskStateUninit = 0, /* only valid within SSLContextAlloc */
+ SSL_HdskStateServerUninit, /* no handshake yet */
+ SSL_HdskStateClientUninit, /* no handshake yet */
+ SSL_HdskStateGracefulClose,
+ SSL_HdskStateErrorClose,
+ SSL_HdskStateNoNotifyClose, /* server disconnected with no
+ * notify msg */
+ /* remainder must be consecutive */
+ SSL_HdskStateServerHello, /* must get server hello; client hello sent */
+ SSL_HdskStateServerHelloUnknownVersion,
+ /* Could get SSL 2 or SSL 3 server hello back */
+ SSL_HdskStateKeyExchange, /* must get key exchange; cipher spec
+ * requires it */
+ SSL_HdskStateCert, /* may get certificate or certificate
+ * request (if no cert request received yet) */
+ SSL_HdskStateHelloDone, /* must get server hello done; after key
+ * exchange or fixed DH parameters */
+ SSL_HdskStateClientCert, /* must get certificate or no cert alert
+ * from client */
+ SSL_HdskStateClientKeyExchange, /* must get client key exchange */
+ SSL_HdskStateClientCertVerify, /* must get certificate verify from client */
+ SSL_HdskStateChangeCipherSpec, /* time to change the cipher spec */
+ SSL_HdskStateFinished, /* must get a finished message in the
+ * new cipher spec */
+ SSL2_HdskStateClientMasterKey,
+ SSL2_HdskStateClientFinished,
+ SSL2_HdskStateServerHello,
+ SSL2_HdskStateServerVerify,
+ SSL2_HdskStateServerFinished,
+ SSL2_HdskStateServerReady, /* ready for I/O; server side */
+ SSL2_HdskStateClientReady /* ready for I/O; client side */
+} SSLHandshakeState;
+
+typedef struct
+{ SSLHandshakeType type;
+ SSLBuffer contents;
+} SSLHandshakeMsg;
+
+#define SSL_Finished_Sender_Server 0x53525652
+#define SSL_Finished_Sender_Client 0x434C4E54
+
+/** sslHandshake.c **/
+typedef OSStatus (*EncodeMessageFunc)(SSLRecord &rec, SSLContext *ctx);
+OSStatus SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx);
+OSStatus SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx);
+OSStatus SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx);
+OSStatus SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx);
+
+/** sslChangeCipher.c **/
+OSStatus SSLEncodeChangeCipherSpec(SSLRecord &rec, SSLContext *ctx);
+OSStatus SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx);
+OSStatus SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx);
+
+/** sslCert.c **/
+OSStatus SSLEncodeCertificate(SSLRecord &certificate, SSLContext *ctx);
+OSStatus SSLProcessCertificate(SSLBuffer message, SSLContext *ctx);
+OSStatus SSLEncodeCertificateRequest(SSLRecord &request, SSLContext *ctx);
+OSStatus SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx);
+OSStatus SSLEncodeCertificateVerify(SSLRecord &verify, SSLContext *ctx);
+OSStatus SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx);
+
+/** sslHandshakeHello.c **/
+OSStatus SSLEncodeServerHello(SSLRecord &serverHello, SSLContext *ctx);
+OSStatus SSLProcessServerHello(SSLBuffer message, SSLContext *ctx);
+OSStatus SSLEncodeClientHello(SSLRecord &clientHello, SSLContext *ctx);
+OSStatus SSLProcessClientHello(SSLBuffer message, SSLContext *ctx);
+OSStatus SSLInitMessageHashes(SSLContext *ctx);
+OSStatus SSLEncodeRSAPremasterSecret(SSLContext *ctx);
+OSStatus SSLEncodeDHPremasterSecret(SSLContext *ctx);
+OSStatus SSLInitPendingCiphers(SSLContext *ctx);
+
+/** sslKeyExchange.c **/
+OSStatus SSLEncodeServerKeyExchange(SSLRecord &keyExch, SSLContext *ctx);
+OSStatus SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx);
+OSStatus SSLEncodeKeyExchange(SSLRecord &keyExchange, SSLContext *ctx);
+OSStatus SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
+
+/** sslHandshakeFinish.c **/
+OSStatus SSLEncodeFinishedMessage(SSLRecord &finished, SSLContext *ctx);
+OSStatus SSLProcessFinished(SSLBuffer message, SSLContext *ctx);
+OSStatus SSLEncodeServerHelloDone(SSLRecord &helloDone, SSLContext *ctx);
+OSStatus SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx);
+OSStatus SSLCalculateFinishedMessage(SSLBuffer finished, SSLBuffer shaMsgState, SSLBuffer md5MsgState, UInt32 senderID, SSLContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSLHANDSHAKE_H_ */
Contains: Apple Keychain routines
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
#define _SSL_KEYCHAIN_H_
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
+#include "sslContext.h"
#ifdef __cplusplus
extern "C" {
#endif
-#if (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
/*
* Given an array of certs (as KCItemRefs) and a destination
* SSLCertificate:
);
#endif ST_KC_KEYS_NEED_REF
-#endif /* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
-
/*
* Add Apple built-in root certs to ctx->trustedCerts.
*/
addBuiltInCerts (
SSLContextRef ctx);
-#if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
+#if ST_MANAGES_TRUSTED_ROOTS
/*
* Given an open Keychain:
* add it to newRootCertKc if the user so allows, and if so, add it to
* trustedCerts.
*/
-SSLErr
+OSStatus
sslAddNewRoot(
SSLContext *ctx,
const CSSM_DATA_PTR rootCert);
-#endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
+#endif /* ST_MANAGES_TRUSTED_ROOTS */
#ifdef __cplusplus
}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslMemory.h
+
+ Contains: memory allocator declarations
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef _SSLMEMORY_H_
+#define _SSLMEMORY_H_ 1
+
+#include "sslContext.h"
+#include "sslPriv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * General purpose allocators
+ */
+void *sslMalloc(UInt32 length);
+void sslFree(void *p);
+void *sslRealloc(void *oldPtr, UInt32 oldLen, UInt32 newLen);
+
+/*
+ * SSLBuffer-oriented allocators
+ */
+OSStatus SSLAllocBuffer(SSLBuffer &buf, UInt32 length, const SSLContext *ctx);
+OSStatus SSLFreeBuffer(SSLBuffer &buf, const SSLContext *ctx);
+OSStatus SSLReallocBuffer(SSLBuffer &buf, UInt32 newSize, const SSLContext *ctx);
+
+/*
+ * Convenience routines
+ */
+UInt8 *sslAllocCopy(const UInt8 *src, UInt32 len);
+OSStatus SSLAllocCopyBuffer(
+ const SSLBuffer &src,
+ SSLBuffer **dst); // buffer itself and data mallocd and returned
+OSStatus SSLCopyBuffer(
+ const SSLBuffer &src,
+ SSLBuffer &dst); // dataÊmallocd and returned
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Contains: Misc. private SSL typedefs
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include "sslBuildFlags.h"
+#include "SecureTransportPriv.h"
#ifdef __cplusplus
extern "C" {
*/
typedef struct SSLContext SSLContext;
-/*
- * Some hard-coded constants.
- */
-
-/* The size of of client- and server-generated random numbers in hello messages. */
-#define SSL_CLIENT_SRVR_RAND_SIZE 32
-
-/* The size of the pre-master and master secrets. */
-#define SSL_RSA_PREMASTER_SECRET_SIZE 48
-#define SSL_MASTER_SECRET_SIZE 48
-
#ifdef __cplusplus
}
#endif
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/* *********************************************************************
+ File: sslRecord.h - SSL Record Layer
+ ****************************************************************** */
+
+#ifndef _SSLRECORD_H_
+#define _SSLRECORD_H_ 1
+
+#include "sslPriv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum
+{ SSL_RecordTypeV2_0,
+ SSL_RecordTypeV3_Smallest = 20,
+ SSL_RecordTypeChangeCipher = 20,
+ SSL_RecordTypeAlert = 21,
+ SSL_RecordTypeHandshake = 22,
+ SSL_RecordTypeAppData = 23,
+ SSL_RecordTypeV3_Largest = 23
+};
+
+typedef struct
+{ UInt8 contentType;
+ SSLProtocolVersion protocolVersion;
+ SSLBuffer contents;
+} SSLRecord;
+
+/*
+ * Slightly smaller that 16384 to make room for a MAC in an SSL 2.0
+ * 3-byte header record
+ */
+#define MAX_RECORD_LENGTH 16300
+
+#define DEFAULT_BUFFER_SIZE 4096
+
+OSStatus SSLReadRecord(
+ SSLRecord &rec,
+ SSLContext *ctx);
+
+OSStatus SSLVerifyMac(
+ UInt8 type,
+ SSLBuffer &data,
+ UInt8 *compareMAC,
+ SSLContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSLRECORD_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/* *********************************************************************
+ File: sslSession.h - SSL Session Interface
+ *********************************************************************/
+
+#ifndef _SSLSESSION_H_
+#define _SSLSESSION_H_ 1
+
+#define SSL_SESSION_ID_LEN 16 /* 16 <= SSL_SESSION_ID_LEN <= 32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSStatus SSLAddSessionData(
+ const SSLContext *ctx);
+OSStatus SSLGetSessionData(
+ SSLBuffer *sessionData,
+ const SSLContext *ctx);
+OSStatus SSLDeleteSessionData(
+ const SSLContext *ctx);
+OSStatus SSLRetrieveSessionID(
+ const SSLBuffer sessionData,
+ SSLBuffer *identifier,
+ const SSLContext *ctx);
+OSStatus SSLRetrieveSessionProtocolVersion(
+ const SSLBuffer sessionData,
+ SSLProtocolVersion *version,
+ const SSLContext *ctx);
+OSStatus SSLInstallSessionFromData(
+ const SSLBuffer sessionData,
+ SSLContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSLSESSION_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+ /************************************************************
+ File: sslUtils.h
+ ************************************************************/
+
+#ifndef _SSLUTILS_H_
+#define _SSLUTILS_H_ 1
+
+#include "SecureTransport.h"
+#include "sslPriv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UInt32 SSLDecodeInt(
+ const unsigned char *p,
+ int length);
+unsigned char *SSLEncodeInt(
+ unsigned char *p,
+ UInt32 value,
+ int length);
+UInt8* SSLEncodeUInt64(
+ UInt8 *p,
+ sslUint64 value);
+void IncrementUInt64(
+ sslUint64 *v);
+
+UInt32 SSLGetCertificateChainLength(
+ const SSLCertificate *c);
+Boolean sslIsSessionActive(
+ const SSLContext *ctx);
+OSStatus sslDeleteCertificateChain(
+ SSLCertificate *certs,
+ SSLContext *ctx);
+
+OSStatus sslTime(
+ UInt32 *tim);
+
+#if SSL_DEBUG
+extern const char *protocolVersStr(
+ SSLProtocolVersion prot);
+#endif
+
+/*
+ * Redirect SSLBuffer-based I/O call to user-supplied I/O.
+ */
+OSStatus sslIoRead(
+ SSLBuffer buf,
+ UInt32 *actualLength,
+ SSLContext *ctx);
+
+OSStatus sslIoWrite(
+ SSLBuffer buf,
+ UInt32 *actualLength,
+ SSLContext *ctx);
+
+/*
+ * Common RNG function.
+ */
+OSStatus sslRand(
+ SSLContext *ctx,
+ SSLBuffer *buf);
+
+
+#define SET_SSL_BUFFER(buf, d, l) do { (buf).data = (d); (buf).length = (l); } while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslalert.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslalert.h Alert layer functions and values
-
- Prototypes for functions in sslalert.c and alert layer equates.
-
- ****************************************************************** */
-
-#ifndef _SSLALERT_H_
-#define _SSLALERT_H_ 1
-
-#ifndef _SECURE_TRANSPORT_H_
-#include "SecureTransport.h"
-#endif
-
-#ifndef _SSL_PRIV_H_
-#include "sslPriv.h"
-#endif
-
-#ifndef _SSLREC_H_
-#include "sslrec.h"
-#endif
-
-typedef enum
-{ alert_warning = 1,
- alert_fatal = 2
-} AlertLevel;
-
-typedef enum
-{ alert_close_notify = 0,
- alert_unexpected_message = 10,
- alert_bad_record_mac = 20,
- alert_decryption_failed = 21, /* TLS */
- alert_record_overflow = 22, /* TLS */
- alert_decompression_failure = 30,
- alert_handshake_failure = 40,
- alert_no_certificate = 41,
- alert_bad_certificate = 42, /* SSLv3 only */
- alert_unsupported_certificate = 43,
- alert_certificate_revoked = 44,
- alert_certificate_expired = 45,
- alert_certificate_unknown = 46,
- alert_illegal_parameter = 47,
- /* remainder are TLS addenda */
- alert_unknown_ca = 48,
- alert_access_denied = 49,
- alert_decode_error = 50,
- alert_decrypt_error = 51,
- alert_export_restriction = 60,
- alert_protocol_version = 70,
- alert_insufficient_security = 71,
- alert_internal_error = 80,
- alert_user_canceled = 90,
- alert_no_renegotiation = 100
-} AlertDescription;
-
-SSLErr SSLProcessAlert(SSLRecord rec, SSLContext *ctx);
-SSLErr SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx);
-SSLErr SSLEncodeAlert(SSLRecord *rec, AlertLevel level, AlertDescription desc, SSLContext *ctx);
-SSLErr SSLFatalSessionAlert(AlertDescription desc, SSLContext *ctx);
-
-#endif /* _SSLALERT_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslalloc.h
-
- Contains: memory allocator declarations
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: sslalloc.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslalloc.h Allocation shell routines
-
- These routines wrap the user-supplied callbacks to provide allocation
- functionality.
-
- ****************************************************************** */
-
-#ifndef _SSLALLOC_H_
-#define _SSLALLOC_H_ 1
-
-#include "sslctx.h"
-#include "sslerrs.h"
-#include "sslPriv.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * General purpose allocators
- */
-void *sslMalloc(UInt32 length);
-void sslFree(void *p);
-void *sslRealloc(void *oldPtr, UInt32 oldLen, UInt32 newLen);
-
-/*
- * SSLBuffer-oriented allocators
- */
-SSLErr SSLAllocBuffer(SSLBuffer *buf, UInt32 length, const SystemContext *ctx);
-SSLErr SSLFreeBuffer(SSLBuffer *buf, const SystemContext *ctx);
-SSLErr SSLReallocBuffer(SSLBuffer *buf, UInt32 newSize, const SystemContext *ctx);
-
-/*
- * Convenience routines.
- */
-UInt8 *sslAllocCopy(const UInt8 *src, UInt32 len);
-SSLErr SSLAllocCopyBuffer(
- const SSLBuffer *src,
- SSLBuffer **dst); // buffer itself and data mallocd and returned
-SSLErr SSLCopyBuffer(
- const SSLBuffer *src,
- SSLBuffer *dst); // dataÊmallocd and returned
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslctx.h
-
- Contains: Private SSL typedefs: SSLContext and its components
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-/* *********************************************************************
- File: sslctx.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslctx.h Internal state of an SSL connection
-
- Contains the SSLContext structure which encapsulates the state of the
- connection at any time. Whenever SSLREF might have to return (mostly
- when I/O is done), this structure must completely represent the
- connection state
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#define _SSLCTX_H_ 1
-
-#include <Security/SecureTransport.h>
-#include "sslBuildFlags.h"
-#include <Security/cssmtype.h>
-
-#include "sslerrs.h"
-#include "sslPriv.h"
-#include "tls_ssl.h"
-
-typedef struct
-{ SSLReadFunc read;
- SSLWriteFunc write;
- SSLConnectionRef ioRef;
-} IOContext;
-
-struct SystemContext
-{
- /*
- * This struct is a remnant of the original SSLRef implementation; it
- * held things like caller-provided memory allocator callbacks.
- * We'll keep the struct (and an instance of it in SSLContext, below)
- * around in case we want to use it in SSLAllocBuffer and its siblings.
- */
- int foo;
-};
-
-typedef struct SystemContext SystemContext;
-
-/*
- * A carryover from original SSLRef 3.0 - we'll store the DER-encoded
- * certs in an SSLCertificate this way for now; there's a lot of code
- * which munges these lists.
- */
-typedef struct SSLCertificate
-{
- struct SSLCertificate *next;
- SSLBuffer derCert;
-} SSLCertificate;
-
-#include "cryptType.h"
-
-/*
- * An SSLContext contains four of these - one for each of {read,write} and for
- * {current, pending}.
- */
-struct CipherContext
-{
-
- const HashHmacReference *macRef; /* HMAC (TLS) or digest (SSL) */
- const SSLSymmetricCipher *symCipher;
-
- /* this is a context which is reused once per record */
- HashHmacContext macCtx;
-
- /*
- * symKey is obtained from the CSP at cspHand. Normally this
- * cspHand is the same as ctx->cspHand; some day they might differ.
- * Code which deals with this struct doesn't ever have to
- * attach or detach from cspHand - that's taken care of at the
- * SSLContext level.
- */
- CSSM_KEY_PTR symKey;
- CSSM_CSP_HANDLE cspHand;
- CSSM_CC_HANDLE ccHand;
-
- /* needed in CDSASymmInit */
- uint8 encrypting;
-
- sslUint64 sequenceNum;
- uint8 ready;
-
- /* in SSL2 mode, the macSecret is the same size as the
- * cipher key - which is 24 bytes in the 3DES case. */
- uint8 macSecret[MAX_SYMKEY_SIZE];
-};
-/* typedef in cryptType.h */
-
-#include "sslhdshk.h"
-
-typedef struct WaitingRecord
-{ struct WaitingRecord *next;
- SSLBuffer data;
- uint32 sent;
-} WaitingRecord;
-
-typedef struct DNListElem
-{ struct DNListElem *next;
- SSLBuffer derDN;
-} DNListElem;
-
-struct SSLContext
-{
- /*
- * For Apple CDSA version, SystemContext is empty; we'll leave it in for now
- * because it gets passed around so often for SSLAllocBuffer().
- */
- SystemContext sysCtx;
- IOContext ioCtx;
-
- /*
- * For the first two, SSL_Version_Undetermined means "get the best we
- * can, up to macProtocolVersion".
- */
- SSLProtocolVersion reqProtocolVersion; /* requested by app */
- SSLProtocolVersion negProtocolVersion; /* negotiated */
- SSLProtocolVersion maxProtocolVersion; /* max allowed by app */
- SSLProtocolSide protocolSide;
- const struct _SslTlsCallouts *sslTslCalls; /* selects between SSLv3 and TLSv1 */
-
- /* crypto state in CDSA-centric terms */
-
- CSSM_KEY_PTR signingPrivKey;/* our private signing key */
- CSSM_KEY_PTR signingPubKey; /* our public signing key */
- CSSM_CSP_HANDLE signingKeyCsp; /* associated DL/CSP */
- #if ST_KEYCHAIN_ENABLE
- #if ST_KC_KEYS_NEED_REF
- SecKeychainRef signingKeyRef; /* for signingPrivKey */
- #else
- void *signingKeyRef; /* TBD */
- #endif /* ST_KC_KEYS_NEED_REF */
- #endif
-
- /* this stuff should probably be #if ST_SERVER_MODE_ENABLE.... */
- CSSM_KEY_PTR encryptPrivKey;/* our private encrypt key, for
- * server-initiated key exchange */
- CSSM_KEY_PTR encryptPubKey; /* public version of above */
- CSSM_CSP_HANDLE encryptKeyCsp;
- #if ST_KEYCHAIN_ENABLE
- #if ST_KC_KEYS_NEED_REF
- SecKeychainRef encryptKeyRef; /* for signingPrivKey */
- #else
- void *encryptKeyRef; /* TBD */
- #endif /* ST_KC_KEYS_NEED_REF */
- #endif /* ST_KEYCHAIN_ENABLE */
-
- CSSM_KEY_PTR peerPubKey;
- CSSM_CSP_HANDLE peerPubKeyCsp; /* may not be needed, we figure this
- * one out by trial&error, right? */
-
- /*
- * Various cert chains stored in an SSLRef-centric way for now
- * (see comments above re: SSLCertificate).
- * For all three, the root is the first in the chain.
- */
- SSLCertificate *localCert;
- SSLCertificate *encryptCert;
- SSLCertificate *peerCert;
-
- /*
- * trusted root certs; specific to this implementation, we'll store
- * them conveniently...these will be used as AnchorCerts in a TP
- * call.
- */
- UInt32 numTrustedCerts;
- CSSM_DATA_PTR trustedCerts;
-
- /*
- * Keychain to which newly encountered root certs are attempted
- * to be added. AccessCreds untyped for now.
- */
- #if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
- SecKeychainRef newRootCertKc;
- void *accessCreds;
- #endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
-
- /* for symmetric cipher and RNG */
- CSSM_CSP_HANDLE cspHand;
-
- /* session-wide handles for Apple TP, CL */
- CSSM_TP_HANDLE tpHand;
- CSSM_CL_HANDLE clHand;
-
- #if ST_FAKE_KEYCHAIN || ST_FAKE_GET_CSPDL_HANDLE
- /* we manually attach to this for now; eventually we get it from KC */
- CSSM_CSP_HANDLE cspDlHand;
- #endif
-
- /* FIXME - how will we represent this? */
- void *dhAnonParams;
- void *peerDHParams;
-
- Boolean allowExpiredCerts;
-
- SSLBuffer sessionID;
-
- SSLBuffer dhPeerPublic;
- SSLBuffer dhExchangePublic;
- SSLBuffer dhPrivate;
-
- SSLBuffer peerID;
- SSLBuffer resumableSession;
-
- char *peerDomainName;
- UInt32 peerDomainNameLen;
-
- CipherContext readCipher;
- CipherContext writeCipher;
- CipherContext readPending;
- CipherContext writePending;
-
- uint16 selectedCipher; /* currently selected */
- const SSLCipherSpec *selectedCipherSpec; /* ditto */
- SSLCipherSpec *validCipherSpecs; /* context's valid specs */
- unsigned numValidCipherSpecs; /* size of validCipherSpecs */
- SSLHandshakeState state;
-
- #if ST_SERVER_MODE_ENABLE
- SSLAuthenticate clientAuth; /* kNeverAuthenticate, etc. */
- Boolean tryClientAuth;
- #endif /* ST_SERVER_MODE_ENABLE */
- int certRequested;
- int certSent;
- int certReceived;
- int x509Requested;
- DNListElem *acceptableDNList;
-
- uint8 clientRandom[SSL_CLIENT_SRVR_RAND_SIZE];
- uint8 serverRandom[SSL_CLIENT_SRVR_RAND_SIZE];
- SSLBuffer preMasterSecret;
- uint8 masterSecret[48];
-
- /* running digests of all handshake messages */
- SSLBuffer shaState, md5State;
-
- SSLBuffer fragmentedMessageCache;
-
- int ssl2ChallengeLength;
- int ssl2ConnectionIDLength;
- int ssl2SessionMatch;
-
-/* Record layer fields */
- SSLBuffer partialReadBuffer;
- uint32 amountRead;
-
-/* Transport layer fields */
- WaitingRecord *recordWriteQueue;
- SSLBuffer receivedDataBuffer;
- uint32 receivedDataPos;
-
- Boolean allowAnyRoot; // don't require known roots
- #if SSL_DEBUG
- char *rootCertName; // if non-null, write root cert here
- #endif /* SSL_DEBUG */
-
-};
-
-#endif /* _SSLCTX_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslerrs.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslerrs.h Errors SSLRef can return
-
-
- ****************************************************************** */
-
-#ifndef _SSLERRS_H_
-#define _SSLERRS_H_ 1
-
-/*
- * FIXME - we should eventually do away with these and just use the ones
- * on SecureTransport.h. For now, public functions (mostly in sslctx.h)
- * call sslErrToOsStatus() to map these to the apropriate OSStatus.
- *
- * If you add to this, add to errSSLxxx list in SecureTransport.h and also
- * to the sslErrMap map in appleGlue.c.
- */
-typedef enum
-{ SSLNoErr = 0,
- SSLMemoryErr,
- SSLUnsupportedErr,
- SSLProtocolErr,
- SSLNegotiationErr,
- SSLFatalAlert,
- SSLWouldBlockErr,
- SSLIOErr,
- SSLSessionNotFoundErr,
- SSLConnectionClosedGraceful,
- SSLConnectionClosedError,
- X509CertChainInvalidErr,
- SSLBadCert,
-
- /* new errors for APPLE_CDSA */
- SSLCryptoError,
- SSLInternalError,
- SSLAttachFailure, /* CSSM_ModuleAttach failure */
- SSLDataOverflow, /* data buffer overflow */
- SSLUnknownRootCert, /* valid cert chain, untrusted root */
- SSLNoRootCert, /* cert chain not verified by root */
- SSLCertExpired, /* chain had an expired cert */
- SSLBadStateErr, /* connection in wrong state */
- SSLCertNotYetValid,
- SSLConnectionClosedNoNotify, /* server closed session with no
- * notification */
- /* etc. */
-
- SSL_NoSuchError /* no comma, get it? */
-} SSLErr;
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslhdshk.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslhdshk.h SSL Handshake Layer
-
- Prototypes, values, and types for the SSL handshake state machine and
- handshake decoding routines.
-
- ****************************************************************** */
-
-#ifndef _SSLHDSHK_H_
-#define _SSLHDSHK_H_ 72
-
-#ifndef _SSL_H_
-//#include "ssl.h"
-#endif
-
-#ifndef _CRYPTYPE_H_
-#include "cryptType.h"
-#endif
-
-#ifndef _SSLREC_H_
-#include "sslrec.h"
-#endif
-
-typedef enum
-{ SSL_hello_request = 0,
- SSL_client_hello = 1,
- SSL_server_hello = 2,
- SSL_certificate = 11,
- SSL_server_key_exchange = 12,
- SSL_certificate_request = 13,
- SSL_server_hello_done = 14,
- SSL_certificate_verify = 15,
- SSL_client_key_exchange = 16,
- SSL_finished = 20,
- SSL_MAGIC_no_certificate_alert = 100
-} SSLHandshakeType;
-
-typedef enum
-{ SSL_read,
- SSL_write
-} CipherSide;
-
-typedef enum
-{
- SSLUninitialized = 0, /* only valid within SSLContextAlloc */
- HandshakeServerUninit, /* no handshake yet */
- HandshakeClientUninit, /* no handshake yet */
- SSLGracefulClose,
- SSLErrorClose,
- SSLNoNotifyClose, /* server disconnected with no
- * notify msg */
- /* remainder must be consecutive */
- HandshakeServerHello, /* must get server hello; client hello sent */
- HandshakeServerHelloUnknownVersion, /* Could get SSL 2 or SSL 3 server hello back */
- HandshakeKeyExchange, /* must get key exchange; cipher spec requires it */
- HandshakeCertificate, /* may get certificate or certificate request (if no cert request received yet) */
- HandshakeHelloDone, /* must get server hello done; after key exchange or fixed DH parameters */
- HandshakeClientCertificate, /* must get certificate or no cert alert from client */
- HandshakeClientKeyExchange, /* must get client key exchange */
- HandshakeClientCertVerify, /* must get certificate verify from client */
- HandshakeChangeCipherSpec, /* time to change the cipher spec */
- HandshakeFinished, /* must get a finished message in the new cipher spec */
- HandshakeSSL2ClientMasterKey,
- HandshakeSSL2ClientFinished,
- HandshakeSSL2ServerHello,
- HandshakeSSL2ServerVerify,
- HandshakeSSL2ServerFinished,
- HandshakeServerReady, /* ready for I/O; server side */
- HandshakeClientReady /* ready for I/O; client side */
-} SSLHandshakeState;
-
-typedef struct
-{ SSLHandshakeType type;
- SSLBuffer contents;
-} SSLHandshakeMsg;
-
-#define SSL_Finished_Sender_Server 0x53525652
-#define SSL_Finished_Sender_Client 0x434C4E54
-
-/** sslhdshk.c **/
-typedef SSLErr (*EncodeMessageFunc)(SSLRecord *rec, SSLContext *ctx);
-SSLErr SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx);
-SSLErr SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx);
-SSLErr SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx);
-SSLErr SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx);
-
-/** hdskchgc.c **/
-SSLErr SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx);
-SSLErr SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx);
-SSLErr SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx);
-
-/** hdskcert.c **/
-SSLErr SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx);
-SSLErr SSLProcessCertificate(SSLBuffer message, SSLContext *ctx);
-SSLErr SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx);
-SSLErr SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx);
-SSLErr SSLEncodeCertificateVerify(SSLRecord *verify, SSLContext *ctx);
-SSLErr SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx);
-
-/** hdskhelo.c **/
-SSLErr SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx);
-SSLErr SSLProcessServerHello(SSLBuffer message, SSLContext *ctx);
-SSLErr SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx);
-SSLErr SSLProcessClientHello(SSLBuffer message, SSLContext *ctx);
-SSLErr SSLInitMessageHashes(SSLContext *ctx);
-
-/** hdskkyex.c **/
-SSLErr SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
-SSLErr SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx);
-SSLErr SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
-SSLErr SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
-
-/** hdskfini.c **/
-SSLErr SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx);
-SSLErr SSLProcessFinished(SSLBuffer message, SSLContext *ctx);
-SSLErr SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx);
-SSLErr SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx);
-SSLErr SSLCalculateFinishedMessage(SSLBuffer finished, SSLBuffer shaMsgState, SSLBuffer md5MsgState, UInt32 senderID, SSLContext *ctx);
-
-/** hdskkeys.c **/
-SSLErr SSLEncodeRSAPremasterSecret(SSLContext *ctx);
-SSLErr SSLEncodeDHPremasterSecret(SSLContext *ctx);
-SSLErr SSLInitPendingCiphers(SSLContext *ctx);
-
-#endif /* _SSLHDSHK_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslrec.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslrec.h SSL Record Layer
-
- Prototypes, values, and types for the SSL record layer.
-
- ****************************************************************** */
-
-#ifndef _SSLREC_H_
-#define _SSLREC_H_ 1
-
-#ifndef _SSL_PRIV_H_
-#include "sslPriv.h"
-#endif /* _SSL_PRIV_H_ */
-
-#ifndef _SSLERRS_H_
-#include "sslerrs.h"
-#endif
-
-enum
-{ SSL_version_2_0_record,
- SSL_smallest_3_0_type = 20,
- SSL_change_cipher_spec = 20,
- SSL_alert = 21,
- SSL_handshake = 22,
- SSL_application_data = 23,
- SSL_largest_3_0_type = 23
-};
-
-typedef struct
-{ UInt8 contentType;
- SSLProtocolVersion protocolVersion;
- SSLBuffer contents;
-} SSLRecord;
-
-#define MAX_RECORD_LENGTH 16300 /* Slightly smaller that 16384 to make room for a MAC in an SSL 2.0 3-byte header record */
-
-#define DEFAULT_BUFFER_SIZE 4096
-
-SSLErr SSLReadRecord(SSLRecord *rec, SSLContext *ctx);
-
-SSLErr SSLVerifyMac(
- UInt8 type,
- SSLBuffer data,
- UInt8 *compareMAC,
- SSLContext *ctx);
-
-#endif /* _SSLREC_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslsess.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslsess.h SSL Session Interface
-
- Prototypes for the SSL session interface functions in sslsess.c.
-
- ****************************************************************** */
-
-#ifndef _SSLSESS_H_
-#define _SSLSESS_H_ 1
-
-#define SSL_SESSION_ID_LEN 16 /* 16 <= SSL_SESSION_ID_LEN <= 32 */
-
-SSLErr SSLAddSessionData(const SSLContext *ctx);
-SSLErr SSLGetSessionData(SSLBuffer *sessionData, const SSLContext *ctx);
-SSLErr SSLDeleteSessionData(const SSLContext *ctx);
-SSLErr SSLRetrieveSessionID(
- const SSLBuffer sessionData,
- SSLBuffer *identifier,
- const SSLContext *ctx);
-SSLErr SSLRetrieveSessionProtocolVersion(
- const SSLBuffer sessionData,
- SSLProtocolVersion *version,
- const SSLContext *ctx);
-SSLErr SSLInstallSessionFromData(const SSLBuffer sessionData, SSLContext *ctx);
-
-#endif /* _SSLSESS_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: ssltrspt.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ssltrspt.h SSL Transport Layer
-
- A single fabulous prototype for the single function in ssltrspt.h
- which isn't in ssl.h. You have found the SSLRef easter egg (such as
- it is). SSLRef by Tim Dierks, with help from Eric Gundrum, Chris
- Allen, Jonathan Zamick, and Michael Rutman. Thanks also to Jim
- CastroLang, Clare Burmeister, and Tony Hughes. Also, thanks to our
- friends at Netscape: Tom Weinstein, Jeff Weinstein, Phil Karlton, and
- Eric Greenberg.
-
- ****************************************************************** */
-
-#ifndef _SSLTRSPT_H_
-#define _SSLTRSPT_H_ 1
-
-#ifndef _SSL_H_
-#include "ssl.h"
-#endif
-
-#ifndef _SSLREC_H_
-#include "sslrec.h"
-#endif
-
-SSLErr QueueMessage(SSLRecord rec, SSLContext *ctx);
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslutil.h
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslutil.h Utility functions
-
- These functions get used in message decoding all over the place.
-
- ****************************************************************** */
-
-#ifndef _SSLUTIL_H_
-#define _SSLUTIL_H_ 1
-
-#ifndef _SECURE_TRANSPORT_H_
-#include "SecureTransport.h"
-#endif
-
-#ifndef _SSL_PRIV_H_
-#include "sslPriv.h"
-#endif
-
-UInt32 SSLDecodeInt(const unsigned char *p, int length);
-unsigned char *SSLEncodeInt(unsigned char *p, UInt32 value, int length);
-UInt8* SSLEncodeUInt64(UInt8 *p, sslUint64 value);
-void IncrementUInt64(sslUint64 *v);
-
-UInt32 SSLGetCertificateChainLength(const SSLCertificate *c);
-Boolean sslIsSessionActive(const SSLContext *ctx);
-OSStatus sslDeleteCertificateChain(SSLCertificate *certs, SSLContext *ctx);
-
-#if SSL_DEBUG
-extern const char *protocolVersStr(SSLProtocolVersion prot);
-#endif
-
-#define SET_SSL_BUFFER(buf, d, l) do { (buf).data = (d); (buf).length = (l); } while (0)
-
-#endif
Contains: CDSA-based symmetric cipher module
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
+ Written by: Doug Mitchell
Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
#ifndef _SYM_CIPHER_H_
#define _SYM_CIPHER_H_
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _CRYPTTYPE_H_
+#include "sslContext.h"
#include "cryptType.h"
-#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
* All symmetric cipher logic goes thru these same four routines, on the
* way down to CDSA
*/
-SSLErr CDSASymmInit(
+OSStatus CDSASymmInit(
uint8 *key,
uint8* iv,
CipherContext *cipherCtx,
SSLContext *ctx);
-SSLErr CDSASymmEncrypt(
+OSStatus CDSASymmEncrypt(
SSLBuffer src,
SSLBuffer dest,
CipherContext *cipherCtx,
SSLContext *ctx);
-SSLErr CDSASymmDecrypt(
+OSStatus CDSASymmDecrypt(
SSLBuffer src,
SSLBuffer dest,
CipherContext *cipherCtx,
SSLContext *ctx);
-SSLErr CDSASymmFinish(
+OSStatus CDSASymmFinish(
CipherContext *cipherCtx,
SSLContext *ctx);
-#endif /* _SYM_CIPHER_H_ */
\ No newline at end of file
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYM_CIPHER_H_ */
#include "ssl.h"
#include "sslPriv.h"
-//#include "sslctx.h"
-#include "sslerrs.h"
/* forward declaration of HMAC object */
struct HMACReference;
#define TLS_HMAC_MAX_SIZE 20
/* Create an HMAC session */
-typedef SSLErr (*HMAC_AllocFcn) (
+typedef OSStatus (*HMAC_AllocFcn) (
const struct HMACReference *hmac,
SSLContext *ctx,
const void *keyPtr,
HMACContextRef *hmacCtx); // RETURNED
/* Free a session */
-typedef SSLErr (*HMAC_FreeFcn) (
+typedef OSStatus (*HMAC_FreeFcn) (
HMACContextRef hmacCtx);
/* Reusable init, using same key */
-typedef SSLErr (*HMAC_InitFcn) (
+typedef OSStatus (*HMAC_InitFcn) (
HMACContextRef hmacCtx);
/* normal crypt ops */
-typedef SSLErr (*HMAC_UpdateFcn) (
+typedef OSStatus (*HMAC_UpdateFcn) (
HMACContextRef hmacCtx,
const void *data,
unsigned dataLen);
-typedef SSLErr (*HMAC_FinalFcn) (
+typedef OSStatus (*HMAC_FinalFcn) (
HMACContextRef hmacCtx,
void *hmac, // mallocd by caller
unsigned *hmacLen); // IN/OUT
/* one-shot */
-typedef SSLErr (*HMAC_HmacFcn) (
+typedef OSStatus (*HMAC_HmacFcn) (
HMACContextRef hmacCtx,
const void *data,
unsigned dataLen,
#include "ssl.h"
#include "sslPriv.h"
-#include "sslctx.h"
-#include "sslrec.h"
+#include "sslContext.h"
+#include "sslRecord.h"
#include "cryptType.h"
/***
***/
/* unpack, decrypt, validate one record */
-typedef SSLErr (*decryptRecordFcn) (
+typedef OSStatus (*decryptRecordFcn) (
UInt8 type,
SSLBuffer *payload,
SSLContext *ctx);
/* pack, encrypt, mac, queue one outgoing record */
-typedef SSLErr (*writeRecordFcn) (
+typedef OSStatus (*writeRecordFcn) (
SSLRecord rec,
SSLContext *ctx);
/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
-typedef SSLErr (*initMacFcn) (
+typedef OSStatus (*initMacFcn) (
CipherContext *cipherCtx, // macRef, macSecret valid on entry
// macCtx valid on return
SSLContext *ctx);
/* free per-CipherContext HashHmacContext */
-typedef SSLErr (*freeMacFcn) (
+typedef OSStatus (*freeMacFcn) (
CipherContext *cipherCtx);
/* compute MAC on one record */
-typedef SSLErr (*computeMacFcn) (
+typedef OSStatus (*computeMacFcn) (
UInt8 type,
SSLBuffer data,
SSLBuffer mac, // caller mallocs data
sslUint64 seqNo,
SSLContext *ctx);
-typedef SSLErr (*generateKeyMaterialFcn) (
+typedef OSStatus (*generateKeyMaterialFcn) (
SSLBuffer key, // caller mallocs and specifies length of
// required key material here
SSLContext *ctx);
-typedef SSLErr (*generateExportKeyAndIvFcn) (
+typedef OSStatus (*generateExportKeyAndIvFcn) (
SSLContext *ctx, // clientRandom, serverRandom valid
const SSLBuffer clientWriteKey,
const SSLBuffer serverWriteKey,
* On entry: clientRandom, serverRandom, preMasterSecret valid
* On return: masterSecret valid
*/
-typedef SSLErr (*generateMasterSecretFcn) (
+typedef OSStatus (*generateMasterSecretFcn) (
SSLContext *ctx);
-typedef SSLErr (*computeFinishedMacFcn) (
+typedef OSStatus (*computeFinishedMacFcn) (
SSLContext *ctx,
SSLBuffer finished, // output - mallocd by caller
SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
SSLBuffer md5MsgState, // ditto
Boolean isServer);
-typedef SSLErr (*computeCertVfyMacFcn) (
+typedef OSStatus (*computeCertVfyMacFcn) (
SSLContext *ctx,
SSLBuffer finished, // output - mallocd by caller
SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
extern const SslTlsCallouts Tls1Callouts;
/* one callout routine used in common (for now) */
-SSLErr ssl3WriteRecord(
+OSStatus ssl3WriteRecord(
SSLRecord rec,
SSLContext *ctx);
//
// Open initiates or continues the SSL handshake.
// In nonblocking mode, open may return while handshake is still in
-// progress. Keep calling open until state() != errSSLWouldBlock, or
+// Progress. Keep calling open until state() != errSSLWouldBlock, or
// go directly to I/O.
//
void SecureTransportCore::open()
//
// Continue handshake processing if necessary.
-// Returns true if handshake is in progress and not yet complete.
+// Returns true if handshake is in Progress and not yet complete.
//
bool SecureTransportCore::continueHandshake()
{
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*************************************************************************
+ File: ssl2CipherMap.cpp Maps SSL 2 cipher kinds to SSL 3 cipher suites
+ *************************************************************************/
+
+#include "sslContext.h"
+#include "cryptType.h"
+
+const SSLCipherMapping SSL2CipherMap[] =
+{ { SSL2_RC4_128_WITH_MD5, SSL_RSA_WITH_RC4_128_MD5 },
+ { SSL2_RC4_128_EXPORT_40_WITH_MD5, SSL_RSA_EXPORT_WITH_RC4_40_MD5 },
+ { SSL2_RC2_128_CBC_WITH_MD5, SSL_RSA_WITH_RC2_CBC_MD5 },
+ { SSL2_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 },
+ { SSL2_IDEA_128_CBC_WITH_MD5, SSL_RSA_WITH_IDEA_CBC_MD5 },
+ { SSL2_DES_64_CBC_WITH_MD5, SSL_RSA_WITH_DES_CBC_MD5 },
+ { SSL2_DES_192_EDE3_CBC_WITH_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5}
+};
+
+const unsigned SSL2CipherMapCount = sizeof(SSL2CipherMap) / sizeof(SSLCipherMapping);
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+#include "ssl.h"
+#include "ssl2.h"
+#include "sslRecord.h"
+#include "sslMemory.h"
+#include "sslContext.h"
+#include "sslAlertMessage.h"
+#include "sslHandshake.h"
+#include "sslSession.h"
+#include "sslDebug.h"
+#include "cipherSpecs.h"
+#include "appleCdsa.h"
+#include "sslUtils.h"
+
+#include <string.h>
+#include <assert.h>
+
+OSStatus
+SSL2ProcessClientHello(SSLBuffer msg, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 *charPtr, *cipherList;
+ unsigned i, j, cipherKindCount, sessionIDLen, challengeLen;
+ SSL2CipherKind cipherKind;
+ SSLCipherSuite matchingCipher, selectedCipher;
+ SSLProtocolVersion version;
+
+ if (msg.length < 27) {
+ sslErrorLog("SSL2ProcessClientHello: msg len error 1\n");
+ return errSSLProtocol;
+ }
+
+ charPtr = msg.data;
+
+ version = (SSLProtocolVersion)SSLDecodeInt(charPtr, 2);
+ if (version > ctx->maxProtocolVersion) {
+ version = ctx->maxProtocolVersion;
+ }
+ /* FIXME - I think this needs work for a SSL_Version_2_0 server, to ensure that
+ * the client isn't establishing a v3 session. */
+ if (ctx->negProtocolVersion == SSL_Version_Undetermined)
+ {
+ /* FIXME - this ifndef should not be necessary */
+ #ifndef NDEBUG
+ sslLogNegotiateDebug("===SSL2 server: negVersion was undetermined; "
+ "is %s", protocolVersStr(version));
+ #endif
+ ctx->negProtocolVersion = version;
+ if(version >= TLS_Version_1_0) {
+ ctx->sslTslCalls = &Tls1Callouts;
+ }
+ else {
+ /* default from context init */
+ assert(ctx->sslTslCalls == &Ssl3Callouts);
+ }
+ }
+ else if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
+ { if (version < SSL_Version_3_0) {
+ sslErrorLog("SSL2ProcessClientHello: version error\n");
+ return errSSLProtocol;
+ }
+ /* FIXME - I don't think path is ever taken - we NEVER set any
+ * protocol var to SSL_Version_3_0_With_2_0_Hello... */
+ sslLogNegotiateDebug("===SSL2 server: negVersion was "
+ "3_0_With_2_0_Hello; is 3_0");
+ ctx->negProtocolVersion = version;
+ }
+
+ charPtr += 2;
+ cipherKindCount = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ if (cipherKindCount % 3 != 0) {
+ sslErrorLog("SSL2ProcessClientHello: cipherKindCount error\n");
+ return errSSLProtocol;
+ }
+ cipherKindCount /= 3;
+ sessionIDLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ challengeLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+
+ if (msg.length != 8 + 3*cipherKindCount + sessionIDLen + challengeLen ||
+ (sessionIDLen != 0 && sessionIDLen != 16) ||
+ challengeLen < 16 || challengeLen > 32 ) {
+ sslErrorLog("SSL2ProcessClientHello: msg len error 2\n");
+ return errSSLProtocol;
+ }
+ cipherList = charPtr;
+ selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
+
+ if (ctx->negProtocolVersion >= SSL_Version_3_0) {
+ /* If we're negotiating an SSL 3.0 session, use SSL 3.0 suites first */
+ for (i = 0; i < cipherKindCount; i++) {
+ cipherKind = (SSL2CipherKind)SSLDecodeInt(charPtr, 3);
+ charPtr += 3;
+ if (selectedCipher != SSL_NO_SUCH_CIPHERSUITE)
+ continue;
+ if ((((UInt32)cipherKind) & 0xFF0000) != 0)
+ continue; /* Skip SSL 2 suites */
+ matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
+ for (j = 0; j<ctx->numValidCipherSpecs; j++) {
+ if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher) {
+ selectedCipher = matchingCipher;
+ break;
+ }
+ } /* searching thru all our valid ciphers */
+ } /* for each client cipher */
+ } /* v3 or greater */
+
+ if(selectedCipher == SSL_NO_SUCH_CIPHERSUITE) {
+ /* try again using SSL2 ciphers only */
+ charPtr = cipherList;
+ for (i = 0; i < cipherKindCount; i++) {
+ cipherKind = (SSL2CipherKind)SSLDecodeInt(charPtr, 3);
+ charPtr += 3;
+ if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) {
+ /* After we find one, just keep advancing ptr past
+ * the unused ones */
+ if ((((UInt32)cipherKind) & 0xFF0000) != 0) {
+ /* If it's a real SSL2 spec, look for it in the list */
+ matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
+ for (j = 0; j < SSL2CipherMapCount; j++) {
+ if (cipherKind == SSL2CipherMap[j].cipherKind) {
+ matchingCipher = SSL2CipherMap[j].cipherSuite;
+ break;
+ }
+ }
+ } /* real 3-byte SSL2 suite */
+ else {
+ /* if the first byte is zero, it's an encoded SSL 3 CipherSuite */
+ matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
+ /*
+ * One more restriction - if we've negotiated a v2 session,
+ * ignore this matching cipher if it's not in the SSL2 map.
+ */
+ if(ctx->negProtocolVersion < SSL_Version_3_0) {
+ int isInMap = 0;
+ for (j = 0; j < SSL2CipherMapCount; j++) {
+ if (matchingCipher == SSL2CipherMap[j].cipherSuite) {
+ isInMap = 1;
+ break;
+ }
+ }
+ if(!isInMap) {
+ /* Sorry, no can do */
+ matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
+ }
+ } /* SSL2 check */
+ } /* two-byte suite */
+
+ /* now see if we are enabled for this cipher */
+ if (matchingCipher != SSL_NO_SUCH_CIPHERSUITE) {
+ for (j = 0; j < ctx->numValidCipherSpecs; j++) {
+ if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher) {
+ selectedCipher = matchingCipher;
+ break;
+ }
+ }
+ }
+ } /* not ignoring this suite */
+ } /* for each suite in the hello msg */
+ } /* not found in SSL3 ciphersuites */
+
+ if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
+ return errSSLNegotiation;
+
+ ctx->selectedCipher = selectedCipher;
+ err = FindCipherSpec(ctx);
+ if(err != 0) {
+ return err;
+ }
+ if (sessionIDLen > 0 && ctx->peerID.data != 0)
+ { /* Don't die on error; just treat it as an uncacheable session */
+ err = SSLAllocBuffer(ctx->sessionID, sessionIDLen, ctx);
+ if (err == 0)
+ memcpy(ctx->sessionID.data, charPtr, sessionIDLen);
+ }
+ charPtr += sessionIDLen;
+
+ ctx->ssl2ChallengeLength = challengeLen;
+ memset(ctx->clientRandom, 0, SSL_CLIENT_SRVR_RAND_SIZE);
+ memcpy(ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE - challengeLen,
+ charPtr, challengeLen);
+ charPtr += challengeLen;
+ assert(charPtr == msg.data + msg.length);
+
+ return noErr;
+}
+
+/*
+ * The SSL v2 spec says that the challenge string sent by the client can be
+ * between 16 and 32 bytes. However all Netscape enterprise servers actually
+ * require a 16 byte challenge. Q.v. cdnow.com, store.apple.com.
+ * Unfortunately this means that when we're trying to do a
+ * SSL_Version_3_0_With_2_0_Hello negotiation, we have to limit ourself to
+ * a 16-byte clientRandom, which we have to concatenate to 16 bytes of
+ * zeroes if we end up with a 3.0 or 3.1 connection. Thus we lose 16 bytes
+ * of entropy.
+ */
+#define SSL2_CHALLENGE_LEN 16
+
+OSStatus
+SSL2EncodeClientHello(SSLBuffer &msg, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 *charPtr;
+ unsigned i, j;
+ int useSSL3Ciphers = 0;
+ int totalCipherCount;
+ int sessionIDLen;
+ UInt16 version;
+ SSLBuffer sessionIdentifier, randomData;
+
+ switch (ctx->negProtocolVersion)
+ { case SSL_Version_Undetermined:
+ case SSL_Version_3_0_With_2_0_Hello:
+ /* go for it, see if server can handle upgrading */
+ useSSL3Ciphers = 1;
+ /* could be SSLv3 or TLSv1 */
+ version = ctx->maxProtocolVersion;
+ break;
+ case SSL_Version_2_0:
+ useSSL3Ciphers = 0;
+ version = SSL_Version_2_0;
+ break;
+ case SSL_Version_3_0_Only:
+ case SSL_Version_3_0:
+ case TLS_Version_1_0_Only:
+ case TLS_Version_1_0:
+ default:
+ assert("Bad protocol version for sending SSL 2 Client Hello");
+ return errSSLInternal;
+ }
+ /* FIXME - this ifndef should not be necessary */
+ #ifndef NDEBUG
+ sslLogNegotiateDebug("===SSL client: proclaiming %s capable",
+ protocolVersStr((SSLProtocolVersion)version));
+ #endif
+
+ if (useSSL3Ciphers != 0)
+ totalCipherCount = ctx->numValidCipherSpecs;
+ else
+ totalCipherCount = 0;
+
+ for (i = 0; i < SSL2CipherMapCount; i++)
+ for (j = 0; j < ctx->numValidCipherSpecs; j++)
+ if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
+ { totalCipherCount++;
+ break;
+ }
+
+ sessionIDLen = 0;
+ sessionIdentifier.data = 0;
+ if (ctx->resumableSession.data != 0)
+ { if ((err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
+ return err;
+ sessionIDLen = sessionIdentifier.length;
+ }
+
+ /* msg length = 9 + 3 * totalCipherCount + sessionIDLen + 16 bytes of challenge
+ * Use exactly 16 bytes of challenge because Netscape products have a bug
+ * that requires this length
+ */
+ if ((err = SSLAllocBuffer(msg, 9 + (3*totalCipherCount) + sessionIDLen +
+ SSL2_CHALLENGE_LEN, ctx)) != 0)
+ { SSLFreeBuffer(sessionIdentifier, ctx);
+ return err;
+ }
+
+ charPtr = msg.data;
+ *charPtr++ = SSL2_MsgClientHello;
+ charPtr = SSLEncodeInt(charPtr, version, 2);
+ charPtr = SSLEncodeInt(charPtr, 3*totalCipherCount, 2);
+ charPtr = SSLEncodeInt(charPtr, sessionIDLen, 2);
+ charPtr = SSLEncodeInt(charPtr, SSL2_CHALLENGE_LEN, 2);
+
+ /* If we can send SSL3 ciphers, encode the two-byte cipher specs into three-byte
+ * CipherKinds which have a leading 0.
+ */
+ if (useSSL3Ciphers != 0)
+ for (i = 0; i < ctx->numValidCipherSpecs; i++)
+ charPtr = SSLEncodeInt(charPtr, ctx->validCipherSpecs[i].cipherSpec, 3);
+
+ /* Now send those SSL2 specs for which we have implementations */
+ for (i = 0; i < SSL2CipherMapCount; i++)
+ for (j = 0; j < ctx->numValidCipherSpecs; j++)
+ if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
+ { charPtr = SSLEncodeInt(charPtr, SSL2CipherMap[i].cipherKind, 3);
+ break;
+ }
+
+ if (sessionIDLen > 0)
+ { memcpy(charPtr, sessionIdentifier.data, sessionIDLen);
+ charPtr += sessionIDLen;
+ SSLFreeBuffer(sessionIdentifier, ctx);
+ }
+
+ randomData.data = charPtr;
+ randomData.length = SSL2_CHALLENGE_LEN;
+ if ((err = sslRand(ctx, &randomData)) != 0)
+ { SSLFreeBuffer(msg, ctx);
+ return err;
+ }
+ charPtr += SSL2_CHALLENGE_LEN;
+
+ /* Zero out the first 16 bytes of clientRandom, and store
+ * the challenge in the second 16 bytes */
+ #if (SSL2_CHALLENGE_LEN == SSL_CLIENT_SRVR_RAND_SIZE)
+ /* this path verified to fail with Netscape Enterprise servers 1/16/02 */
+ memcpy(ctx->clientRandom, randomData.data, SSL2_CHALLENGE_LEN);
+ #else
+ memset(ctx->clientRandom, 0, SSL_CLIENT_SRVR_RAND_SIZE - SSL2_CHALLENGE_LEN);
+ memcpy(ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE - SSL2_CHALLENGE_LEN,
+ randomData.data, SSL2_CHALLENGE_LEN);
+ #endif
+ ctx->ssl2ChallengeLength = SSL2_CHALLENGE_LEN;
+
+ assert(charPtr == msg.data + msg.length);
+
+ return noErr;
+}
+
+OSStatus
+SSL2ProcessClientMasterKey(SSLBuffer msg, SSLContext *ctx)
+{ OSStatus err;
+ SSL2CipherKind cipherKind;
+ SSLBuffer secretData;
+ unsigned clearLength, encryptedLength, keyArgLength;
+ UInt32 secretLength, localKeyModulusLen;
+ UInt8 *charPtr;
+ const CSSM_KEY *decryptKey;
+ CSSM_CSP_HANDLE decryptCspHand;
+
+ if (msg.length < 9) {
+ sslErrorLog("SSL2ProcessClientMasterKey: msg.length error 1\n");
+ return errSSLProtocol;
+ }
+ assert(ctx->protocolSide == SSL_ServerSide);
+
+ charPtr = msg.data;
+ cipherKind = (SSL2CipherKind)SSLDecodeInt(charPtr, 3);
+ charPtr += 3;
+ clearLength = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ encryptedLength = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ keyArgLength = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+
+ if (msg.length != 9 + clearLength + encryptedLength + keyArgLength) {
+ sslErrorLog("SSL2ProcessClientMasterKey: msg.length error 2\n");
+ return errSSLProtocol;
+ }
+
+ /* Master key == CLEAR_DATA || SECRET_DATA */
+ memcpy(ctx->masterSecret, charPtr, clearLength);
+ charPtr += clearLength;
+
+ /*
+ * Just as in SSL2EncodeServerHello, which key we use depends on the
+ * app's config.
+ */
+ if(ctx->encryptPrivKey) {
+ decryptKey = ctx->encryptPrivKey;
+ assert(ctx->encryptKeyCsp != 0);
+ decryptCspHand = ctx->encryptKeyCsp;
+ }
+ else if(ctx->signingPrivKey) {
+ decryptKey = ctx->signingPrivKey;
+ assert(ctx->signingKeyCsp != 0);
+ decryptCspHand = ctx->signingKeyCsp;
+ }
+ else {
+ /* really should not happen... */
+ sslErrorLog("SSL2ProcessClientMasterKey: No server key!\n");
+ return badReqErr;
+ }
+ localKeyModulusLen = sslKeyLengthInBytes(decryptKey);
+
+ if (encryptedLength != localKeyModulusLen) {
+ sslErrorLog("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
+ return errSSLProtocol;
+ }
+
+ /* Allocate enough room to hold any decrypted value */
+ if ((err = SSLAllocBuffer(secretData, encryptedLength, ctx)) != 0)
+ return err;
+
+ err = sslRsaDecrypt(ctx,
+ decryptKey,
+ decryptCspHand,
+ charPtr,
+ encryptedLength,
+ secretData.data,
+ encryptedLength, // same length for both...?
+ &secretLength);
+ if(err) {
+ SSLFreeBuffer(secretData, ctx);
+ return err;
+ }
+
+ charPtr += encryptedLength;
+
+ if (clearLength + secretLength != ctx->selectedCipherSpec->cipher->keySize) {
+ sslErrorLog("SSL2ProcessClientMasterKey: length error 3\n");
+ return errSSLProtocol;
+ }
+ memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
+ if ((err = SSLFreeBuffer(secretData, ctx)) != 0)
+ return err;
+
+ if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize) {
+ sslErrorLog("SSL2ProcessClientMasterKey: length error 4\n");
+ return errSSLProtocol;
+ }
+
+ /* Stash the IV after the master key in master secret storage */
+ memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, charPtr, keyArgLength);
+ charPtr += keyArgLength;
+ assert(charPtr = msg.data + msg.length);
+
+ return noErr;
+}
+
+OSStatus
+SSL2EncodeClientMasterKey(SSLBuffer &msg, SSLContext *ctx)
+{ OSStatus err;
+ unsigned length, i, clearLen;
+ UInt32 outputLen, peerKeyModulusLen;
+ SSLBuffer keyData;
+ UInt8 *charPtr;
+
+ peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
+
+ /* Length is 10 + clear key size + encrypted output size + iv size */
+ length = 10;
+ clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
+ length += clearLen;
+ length += peerKeyModulusLen;
+ length += ctx->selectedCipherSpec->cipher->ivSize;
+
+ if ((err = SSLAllocBuffer(msg, length, ctx)) != 0)
+ return err;
+ charPtr = msg.data;
+ *charPtr++ = SSL2_MsgClientMasterKey;
+ for (i = 0; i < SSL2CipherMapCount; i++)
+ if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
+ break;
+ assert(i < SSL2CipherMapCount);
+ sslLogNegotiateDebug("===SSL2EncodeClientMasterKey: sending cipherKind 0x%x",
+ SSL2CipherMap[i].cipherKind);
+ charPtr = SSLEncodeInt(charPtr, SSL2CipherMap[i].cipherKind, 3);
+ charPtr = SSLEncodeInt(charPtr, clearLen, 2);
+ charPtr = SSLEncodeInt(charPtr, peerKeyModulusLen, 2);
+ charPtr = SSLEncodeInt(charPtr, ctx->selectedCipherSpec->cipher->ivSize, 2);
+
+ /* Generate the keying material; we need enough data for the key and IV */
+ keyData.data = ctx->masterSecret;
+ keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
+ assert(keyData.length <= 48); /* Must be able to store it in the masterSecret array */
+ if ((err = sslRand(ctx, &keyData)) != 0)
+ return err;
+
+ memcpy(charPtr, ctx->masterSecret, clearLen);
+ charPtr += clearLen;
+
+ /* Replace this with code to do encryption at lower level & set PKCS1 padding
+ for rollback attack */
+
+ /*
+ * encrypt only the secret key portion of masterSecret, starting at
+ * clearLen bytes
+ */
+ err = sslRsaEncrypt(ctx,
+ ctx->peerPubKey,
+ ctx->peerPubKeyCsp, // XX - maybe cspHand
+ ctx->masterSecret + clearLen,
+ ctx->selectedCipherSpec->cipher->keySize - clearLen,
+ charPtr,
+ peerKeyModulusLen,
+ &outputLen);
+ if(err) {
+ return err;
+ }
+
+ charPtr += outputLen;
+
+ /* copy clear IV to msg buf */
+ memcpy(charPtr, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
+ ctx->selectedCipherSpec->cipher->ivSize);
+ charPtr += ctx->selectedCipherSpec->cipher->ivSize;
+
+ assert(charPtr == msg.data + msg.length);
+
+ return noErr;
+}
+
+OSStatus
+SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
+{ if (msg.length != ctx->sessionID.length) {
+ sslErrorLog("SSL2ProcessClientFinished: length error\n");
+ return errSSLProtocol;
+ }
+ if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0) {
+ sslErrorLog("SSL2ProcessClientFinished: data compare error\n");
+ return errSSLProtocol;
+ }
+ return noErr;
+}
+
+OSStatus
+SSL2EncodeClientFinished(SSLBuffer &msg, SSLContext *ctx)
+{ OSStatus err;
+
+ if ((err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, ctx)) != 0)
+ return err;
+ msg.data[0] = SSL2_MsgClientFinished;
+ memcpy(msg.data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
+ return noErr;
+}
+
+OSStatus
+SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
+{ OSStatus err;
+ SSL2CertTypeCode certType;
+ unsigned sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
+ unsigned i, j;
+ SSL2CipherKind cipherKind;
+ SSLCertificate *cert;
+ SSLCipherSuite matchingCipher = 0; // avoid compiler warning
+ SSLCipherSuite selectedCipher;
+ UInt8 *charPtr;
+ SSLProtocolVersion version;
+
+ if (msg.length < 10) {
+ sslErrorLog("SSL2ProcessServerHello: length error\n");
+ return errSSLProtocol;
+ }
+ charPtr = msg.data;
+
+ sessionIDMatch = *charPtr++;
+ certType = (SSL2CertTypeCode)*charPtr++;
+ version = (SSLProtocolVersion)SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ if (version != SSL_Version_2_0) {
+ sslErrorLog("SSL2ProcessServerHello: version error\n");
+ return errSSLProtocol;
+ }
+ ctx->negProtocolVersion = version;
+ sslLogNegotiateDebug("===SSL2 client: negVersion is 2_0");
+ certLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ cipherSpecsLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ connectionIDLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+
+ if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
+ (msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
+ return errSSLProtocol;
+ if (sessionIDMatch != 0)
+ { if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
+ return errSSLProtocol;
+ ctx->ssl2SessionMatch = 1;
+
+ ctx->ssl2ConnectionIDLength = connectionIDLen;
+ memcpy(ctx->serverRandom, charPtr, connectionIDLen);
+ charPtr += connectionIDLen;
+ }
+ else
+ { if (certType != SSL2_CertTypeX509)
+ return errSSLNegotiation;
+ cipherSpecsLen /= 3;
+
+ cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
+ if(cert == NULL) {
+ return memFullErr;
+ }
+ cert->next = 0;
+ if ((err = SSLAllocBuffer(cert->derCert, certLen, ctx)) != 0)
+ {
+ sslFree(cert);
+ return err;
+ }
+ memcpy(cert->derCert.data, charPtr, certLen);
+ charPtr += certLen;
+ ctx->peerCert = cert;
+ if((err = sslVerifyCertChain(ctx, *ctx->peerCert)) != 0) {
+ return err;
+ }
+ if((err = sslPubKeyFromCert(ctx,
+ cert->derCert,
+ &ctx->peerPubKey,
+ &ctx->peerPubKeyCsp)) != 0)
+ return err;
+
+ selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
+ for (i = 0; i < cipherSpecsLen; i++)
+ { cipherKind = (SSL2CipherKind)SSLDecodeInt(charPtr, 3);
+ charPtr += 3;
+ if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) /* After we find one, just keep advancing charPtr past the unused ones */
+ { for (j = 0; j < SSL2CipherMapCount; j++)
+ if (cipherKind == SSL2CipherMap[j].cipherKind)
+ { matchingCipher = SSL2CipherMap[j].cipherSuite;
+ break;
+ }
+ for (j = 0; j < ctx->numValidCipherSpecs; j++)
+ if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
+ { selectedCipher = matchingCipher;
+ break;
+ }
+ }
+ }
+ if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
+ return errSSLNegotiation;
+ sslLogNegotiateDebug("===SSL2 client: selectedCipher 0x%x",
+ (unsigned)selectedCipher);
+
+ ctx->selectedCipher = selectedCipher;
+ if ((err = FindCipherSpec(ctx)) != 0) {
+ return err;
+ }
+ ctx->ssl2ConnectionIDLength = connectionIDLen;
+ memcpy(ctx->serverRandom, charPtr, connectionIDLen);
+ charPtr += connectionIDLen;
+ }
+
+ assert(charPtr == msg.data + msg.length);
+
+ return noErr;
+}
+
+OSStatus
+SSL2EncodeServerHello(SSLBuffer &msg, SSLContext *ctx)
+{ OSStatus err;
+ SSLCertificate *cert;
+ SSLBuffer randomData;
+ UInt8 *charPtr;
+ unsigned i;
+
+ /* Create the connection ID */
+ ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
+ randomData.data = ctx->serverRandom;
+ randomData.length = ctx->ssl2ConnectionIDLength;
+ if ((err = sslRand(ctx, &randomData)) != 0)
+ return err;
+
+ if (ctx->ssl2SessionMatch != 0)
+ { if ((err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, ctx)) != 0)
+ return err;
+ charPtr = msg.data;
+ *charPtr++ = SSL2_MsgServerHello;
+ *charPtr++ = ctx->ssl2SessionMatch;
+ *charPtr++ = 0; /* cert type */
+ charPtr = SSLEncodeInt(charPtr, ctx->negProtocolVersion, 2);
+ charPtr = SSLEncodeInt(charPtr, 0, 2); /* cert len */
+ charPtr = SSLEncodeInt(charPtr, 0, 2); /* cipherspecs len */
+ charPtr = SSLEncodeInt(charPtr, ctx->ssl2ConnectionIDLength, 2);
+ memcpy(charPtr, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
+ charPtr += ctx->ssl2ConnectionIDLength;
+ }
+ else
+ { /* First, find the last cert in the chain; it's the one we'll send */
+
+ /*
+ * Use encryptCert if we have it, but allow for the case of app
+ * specifying one cert which can encrypt and sign.
+ */
+ if(ctx->encryptCert != NULL) {
+ cert = ctx->encryptCert;
+ }
+ else if(ctx->localCert != NULL) {
+ cert = ctx->localCert;
+ }
+ else {
+ /* really should not happen... */
+ sslErrorLog("SSL2EncodeServerHello: No server cert!\n");
+ return badReqErr;
+ }
+
+ while (cert->next != 0)
+ cert = cert->next;
+
+ if ((err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, ctx)) != 0)
+ return err;
+ charPtr = msg.data;
+ *charPtr++ = SSL2_MsgServerHello;
+ *charPtr++ = ctx->ssl2SessionMatch;
+ *charPtr++ = SSL2_CertTypeX509; /* cert type */
+
+ /* FIXME - this ifndef should not be necessary */
+ #ifndef NDEBUG
+ sslLogNegotiateDebug("===SSL2 server: sending vers info %s",
+ protocolVersStr((SSLProtocolVersion)ctx->negProtocolVersion));
+ #endif
+
+ charPtr = SSLEncodeInt(charPtr, ctx->negProtocolVersion, 2);
+ charPtr = SSLEncodeInt(charPtr, cert->derCert.length, 2);
+ charPtr = SSLEncodeInt(charPtr, 3, 2); /* cipherspecs len */
+ charPtr = SSLEncodeInt(charPtr, ctx->ssl2ConnectionIDLength, 2);
+ memcpy(charPtr, cert->derCert.data, cert->derCert.length);
+ charPtr += cert->derCert.length;
+ for (i = 0; i < SSL2CipherMapCount; i++)
+ if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
+ break;
+ assert(i < SSL2CipherMapCount);
+ charPtr = SSLEncodeInt(charPtr, SSL2CipherMap[i].cipherKind, 3);
+ sslLogNegotiateDebug("ssl2: server specifying cipherKind 0x%lx",
+ (UInt32)SSL2CipherMap[i].cipherKind);
+ memcpy(charPtr, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
+ charPtr += ctx->ssl2ConnectionIDLength;
+ }
+
+ assert(charPtr == msg.data + msg.length);
+ return noErr;
+}
+
+OSStatus
+SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
+{ if (msg.length != ctx->ssl2ChallengeLength)
+ return errSSLProtocol;
+
+ if (memcmp(msg.data, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
+ ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength) != 0)
+ return errSSLProtocol;
+
+ return noErr;
+}
+
+OSStatus
+SSL2EncodeServerVerify(SSLBuffer &msg, SSLContext *ctx)
+{ OSStatus err;
+
+ if ((err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, ctx)) != 0)
+ return err;
+
+ msg.data[0] = SSL2_MsgServerVerify;
+ memcpy(msg.data+1, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
+ ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength);
+
+ return noErr;
+}
+
+OSStatus
+SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
+{ OSStatus err;
+
+ if ((err = SSLAllocBuffer(ctx->sessionID, msg.length, ctx)) != 0)
+ return err;
+ memcpy(ctx->sessionID.data, msg.data, msg.length);
+ return noErr;
+}
+
+OSStatus
+SSL2EncodeServerFinished(SSLBuffer &msg, SSLContext *ctx)
+{ OSStatus err;
+
+ if ((err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, ctx)) != 0)
+ return err;
+
+ msg.data[0] = SSL2_MsgServerFinished;
+ memcpy(msg.data+1, ctx->sessionID.data, ctx->sessionID.length);
+
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: ssl2Protocol.cpp
+
+ Contains: Protocol engine for SSL 2
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "ssl2.h"
+#include "sslRecord.h"
+#include "sslMemory.h"
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslSession.h"
+#include "sslAlertMessage.h"
+#include "sslDebug.h"
+#include "appleCdsa.h"
+#include "sslUtils.h"
+#include "sslDigests.h"
+#include <string.h>
+#include <assert.h>
+
+#ifndef NDEBUG
+
+static char *sslHdskMsgToStr(SSL2MessageType msg)
+{
+ static char badStr[100];
+
+ switch(msg) {
+ case SSL2_MsgError:
+ return "SSL2_MsgError";
+ case SSL2_MsgClientHello:
+ return "SSL2_MsgClientHello";
+ case SSL2_MsgClientMasterKey:
+ return "SSL2_MsgClientMasterKey";
+ case SSL2_MsgClientFinished:
+ return "SSL2_MsgClientFinished";
+ case SSL2_MsgServerHello:
+ return "SSL2_MsgServerHello";
+ case SSL2_MsgServerVerify:
+ return "SSL2_MsgServerVerify";
+ case SSL2_MsgServerFinished:
+ return "SSL2_MsgServerFinished";
+ case SSL2_MsgRequestCert:
+ return "SSL2_MsgRequestCert";
+ case SSL2_MsgClientCert:
+ return "SSL2_MsgClientCert";
+ case SSL2_MsgKickstart:
+ return "SSL2_MsgKickstart";
+ default:
+ sprintf(badStr, "Unknown msg (%d(d)", msg);
+ return badStr;
+ }
+}
+
+static void logSsl2Msg(SSL2MessageType msg, char sent)
+{
+ char *ms = sslHdskMsgToStr(msg);
+ sslHdskMsgDebug("...msg %s: %s", (sent ? "sent" : "recd"), ms);
+}
+
+#else
+
+#define logSsl2Msg(m, s)
+
+#endif /* NDEBUG */
+
+OSStatus
+SSL2ProcessMessage(SSLRecord &rec, SSLContext *ctx)
+{ OSStatus err = 0;
+ SSL2MessageType msg;
+ SSLBuffer contents;
+
+ if (rec.contents.length < 2)
+ return errSSLProtocol;
+
+ msg = (SSL2MessageType)rec.contents.data[0];
+ contents.data = rec.contents.data + 1;
+ contents.length = rec.contents.length - 1;
+
+ logSsl2Msg(msg, 0);
+
+ switch (msg)
+ { case SSL2_MsgError:
+ err = errSSLClosedAbort;
+ break;
+ case SSL2_MsgClientHello:
+ if (ctx->state != SSL_HdskStateServerUninit)
+ return errSSLProtocol;
+ err = SSL2ProcessClientHello(contents, ctx);
+ if (err == errSSLNegotiation)
+ SSL2SendError(SSL2_ErrNoCipher, ctx);
+ break;
+ case SSL2_MsgClientMasterKey:
+ if (ctx->state != SSL2_HdskStateClientMasterKey)
+ return errSSLProtocol;
+ err = SSL2ProcessClientMasterKey(contents, ctx);
+ break;
+ case SSL2_MsgClientFinished:
+ if (ctx->state != SSL2_HdskStateClientFinished)
+ return errSSLProtocol;
+ err = SSL2ProcessClientFinished(contents, ctx);
+ break;
+ case SSL2_MsgServerHello:
+ if (ctx->state != SSL2_HdskStateServerHello &&
+ ctx->state != SSL_HdskStateServerHelloUnknownVersion)
+ return errSSLProtocol;
+ err = SSL2ProcessServerHello(contents, ctx);
+ if (err == errSSLNegotiation)
+ SSL2SendError(SSL2_ErrNoCipher, ctx);
+ break;
+ case SSL2_MsgServerVerify:
+ if (ctx->state != SSL2_HdskStateServerVerify)
+ return errSSLProtocol;
+ err = SSL2ProcessServerVerify(contents, ctx);
+ break;
+ case SSL2_MsgServerFinished:
+ if (ctx->state != SSL2_HdskStateServerFinished) {
+ /* FIXME - this ifndef should not be necessary */
+ #ifndef NDEBUG
+ sslHdskStateDebug("SSL2_MsgServerFinished; state %s",
+ hdskStateToStr(ctx->state));
+ #endif
+ return errSSLProtocol;
+ }
+ err = SSL2ProcessServerFinished(contents, ctx);
+ break;
+ case SSL2_MsgRequestCert:
+ /* Don't process the request; we don't support client certification */
+ break;
+ case SSL2_MsgClientCert:
+ return errSSLProtocol;
+ break;
+ default:
+ return errSSLProtocol;
+ break;
+ }
+
+ if (err == 0)
+ {
+ /* FIXME - use requested or negotiated protocol version here? */
+ if ((msg == SSL2_MsgClientHello) &&
+ (ctx->negProtocolVersion >= SSL_Version_3_0))
+ { /* Promote this message to SSL 3 protocol */
+ if ((err = SSL3ReceiveSSL2ClientHello(rec, ctx)) != 0)
+ return err;
+ }
+ else
+ err = SSL2AdvanceHandshake(msg, ctx);
+ }
+ return err;
+}
+
+OSStatus
+SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx)
+{ OSStatus err;
+
+ err = noErr;
+
+ switch (msg)
+ { case SSL2_MsgKickstart:
+ if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
+ ctx->negProtocolVersion == SSL_Version_Undetermined)
+ if ((err = SSLInitMessageHashes(ctx)) != 0)
+ return err;
+ if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientHello, ctx)) != 0)
+ return err;
+ switch (ctx->negProtocolVersion)
+ { case SSL_Version_Undetermined:
+ SSLChangeHdskState(ctx, SSL_HdskStateServerHelloUnknownVersion);
+ break;
+ case SSL_Version_3_0_With_2_0_Hello:
+ assert((ctx->reqProtocolVersion == SSL_Version_3_0) ||
+ (ctx->reqProtocolVersion == TLS_Version_1_0));
+ ctx->negProtocolVersion = ctx->reqProtocolVersion;
+ sslLogNegotiateDebug("===SSL client kickstart: negVersion "
+ "is %d_%d",
+ ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
+ SSLChangeHdskState(ctx, SSL_HdskStateServerHello);
+ break;
+ case SSL_Version_2_0:
+ SSLChangeHdskState(ctx, SSL2_HdskStateServerHello);
+ break;
+ case SSL_Version_3_0_Only:
+ case SSL_Version_3_0:
+ case TLS_Version_1_0_Only:
+ case TLS_Version_1_0:
+ default:
+ assert("Bad protocol version for sending SSL 2 Client Hello");
+ break;
+ }
+ break;
+ case SSL2_MsgClientHello:
+ if ((err = SSL2CompareSessionIDs(ctx)) != 0)
+ return err;
+ if (ctx->ssl2SessionMatch == 0)
+ if ((err = SSL2GenerateSessionID(ctx)) != 0)
+ return err;
+ if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerHello, ctx)) != 0)
+ return err;
+ if (ctx->ssl2SessionMatch == 0)
+ { SSLChangeHdskState(ctx, SSL2_HdskStateClientMasterKey);
+ break;
+ }
+ sslLogResumSessDebug("===RESUMING SSL2 server-side session");
+ if ((err = SSL2InstallSessionKey(ctx)) != 0)
+ return err;
+ /* Fall through for matching session; lame, but true */
+ case SSL2_MsgClientMasterKey:
+ if ((err = SSL2InitCiphers(ctx)) != 0)
+ return err;
+ if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerVerify, ctx)) != 0)
+ return err;
+ if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerFinished, ctx)) != 0)
+ return err;
+ SSLChangeHdskState(ctx, SSL2_HdskStateClientFinished);
+ break;
+ case SSL2_MsgServerHello:
+ if (ctx->ssl2SessionMatch == 0)
+ { if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientMasterKey, ctx)) != 0)
+ return err;
+ }
+ else
+ {
+ sslLogResumSessDebug("===RESUMING SSL2 client-side session");
+ if ((err = SSL2InstallSessionKey(ctx)) != 0)
+ return err;
+ }
+ if ((err = SSL2InitCiphers(ctx)) != 0)
+ return err;
+ if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientFinished, ctx)) != 0)
+ return err;
+ SSLChangeHdskState(ctx, SSL2_HdskStateServerVerify);
+ break;
+ case SSL2_MsgClientFinished:
+ /* Handshake is complete; turn ciphers on */
+ ctx->writeCipher.ready = 1;
+ ctx->readCipher.ready = 1;
+ /* original code never got out of SSL2_MsgClientFinished state */
+ assert(ctx->protocolSide == SSL_ServerSide);
+ SSLChangeHdskState(ctx, SSL2_HdskStateServerReady);
+ if (ctx->peerID.data != 0)
+ SSLAddSessionData(ctx);
+ break;
+ case SSL2_MsgServerVerify:
+ SSLChangeHdskState(ctx, SSL2_HdskStateServerFinished);
+ break;
+ case SSL2_MsgRequestCert:
+ if ((err = SSL2SendError(SSL2_ErrNoCert, ctx)) != 0)
+ return err;
+ break;
+ case SSL2_MsgServerFinished:
+ /* Handshake is complete; turn ciphers on */
+ ctx->writeCipher.ready = 1;
+ ctx->readCipher.ready = 1;
+ /* original code never got out of SSL2_MsgServerFinished state */
+ assert(ctx->protocolSide == SSL_ClientSide);
+ SSLChangeHdskState(ctx, SSL2_HdskStateClientReady);
+ if (ctx->peerID.data != 0)
+ SSLAddSessionData(ctx);
+ break;
+ case SSL2_MsgError:
+ case SSL2_MsgClientCert:
+ return errSSLProtocol;
+ break;
+ }
+
+ return noErr;
+}
+
+OSStatus
+SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx)
+{ OSStatus err;
+ SSLRecord rec;
+
+ rec.contentType = SSL_RecordTypeV2_0;
+ rec.protocolVersion = SSL_Version_2_0;
+ if ((err = encodeFunc(rec.contents, ctx)) != 0)
+ return err;
+
+ logSsl2Msg((SSL2MessageType)rec.contents.data[0], 1);
+
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+ { SSLFreeBuffer(rec.contents, ctx);
+ return err;
+ }
+
+ if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
+ ctx->negProtocolVersion == SSL_Version_Undetermined)
+ if ((err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
+ (err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
+ return err;
+
+ err = SSLFreeBuffer(rec.contents, ctx);
+ return err;
+}
+
+OSStatus
+SSL2CompareSessionIDs(SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer sessionIdentifier;
+
+ ctx->ssl2SessionMatch = 0;
+
+ if (ctx->resumableSession.data == 0)
+ return noErr;
+
+ if ((err = SSLRetrieveSessionID(ctx->resumableSession,
+ &sessionIdentifier, ctx)) != 0)
+ return err;
+
+ if (sessionIdentifier.length == ctx->sessionID.length &&
+ memcmp(sessionIdentifier.data, ctx->sessionID.data, sessionIdentifier.length) == 0)
+ ctx->ssl2SessionMatch = 1;
+
+ if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
+ return err;
+
+ return noErr;
+}
+
+OSStatus
+SSL2InstallSessionKey(SSLContext *ctx)
+{ OSStatus err;
+
+ assert(ctx->ssl2SessionMatch != 0);
+ assert(ctx->resumableSession.data != 0);
+ if ((err = SSLInstallSessionFromData(ctx->resumableSession, ctx)) != 0)
+ return err;
+ return noErr;
+}
+
+OSStatus
+SSL2GenerateSessionID(SSLContext *ctx)
+{ OSStatus err;
+
+ if ((err = SSLFreeBuffer(ctx->sessionID, ctx)) != 0)
+ return err;
+ if ((err = SSLAllocBuffer(ctx->sessionID, SSL_SESSION_ID_LEN, ctx)) != 0)
+ return err;
+ if ((err = sslRand(ctx, &ctx->sessionID)) != 0)
+ return err;
+ return noErr;
+}
+
+OSStatus
+SSL2InitCiphers(SSLContext *ctx)
+{ OSStatus err;
+ int keyMaterialLen;
+ SSLBuffer keyData;
+ uint8 variantChar, *charPtr, *readKey, *writeKey, *iv;
+ SSLBuffer hashDigest, hashContext, masterKey, challenge, connectionID, variantData;
+
+ keyMaterialLen = 2 * ctx->selectedCipherSpec->cipher->keySize;
+ if ((err = SSLAllocBuffer(keyData, keyMaterialLen, ctx)) != 0)
+ return err;
+
+ /* Can't have % in assertion string... */
+ #if SSL_DEBUG
+ {
+ UInt32 keyModDigestSize = keyMaterialLen % SSLHashMD5.digestSize;
+ assert(keyModDigestSize == 0);
+ }
+ #endif
+
+ masterKey.data = ctx->masterSecret;
+ masterKey.length = ctx->selectedCipherSpec->cipher->keySize;
+ challenge.data = ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
+ ctx->ssl2ChallengeLength;
+ challenge.length = ctx->ssl2ChallengeLength;
+ connectionID.data = ctx->serverRandom;
+ connectionID.length = ctx->ssl2ConnectionIDLength;
+ variantData.data = &variantChar;
+ variantData.length = 1;
+ if ((err = SSLAllocBuffer(hashContext, SSLHashMD5.contextSize, ctx)) != 0)
+ { SSLFreeBuffer(keyData, ctx);
+ return err;
+ }
+
+ variantChar = 0x30; /* '0' */
+ charPtr = keyData.data;
+ while (keyMaterialLen)
+ { hashDigest.data = charPtr;
+ hashDigest.length = SSLHashMD5.digestSize;
+ if ((err = SSLHashMD5.init(hashContext, ctx)) != 0 ||
+ (err = SSLHashMD5.update(hashContext, masterKey)) != 0 ||
+ (err = SSLHashMD5.update(hashContext, variantData)) != 0 ||
+ (err = SSLHashMD5.update(hashContext, challenge)) != 0 ||
+ (err = SSLHashMD5.update(hashContext, connectionID)) != 0 ||
+ (err = SSLHashMD5.final(hashContext, hashDigest)) != 0)
+ { SSLFreeBuffer(keyData, ctx);
+ SSLFreeBuffer(hashContext, ctx);
+ return err;
+ }
+ charPtr += hashDigest.length;
+ ++variantChar;
+ keyMaterialLen -= hashDigest.length;
+ }
+
+ assert(charPtr == keyData.data + keyData.length);
+
+ if ((err = SSLFreeBuffer(hashContext, ctx)) != 0)
+ { SSLFreeBuffer(keyData, ctx);
+ return err;
+ }
+
+ ctx->readPending.macRef = ctx->selectedCipherSpec->macAlgorithm;
+ ctx->writePending.macRef = ctx->selectedCipherSpec->macAlgorithm;
+ ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
+ ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
+ ctx->readPending.sequenceNum = ctx->readCipher.sequenceNum;
+ ctx->writePending.sequenceNum = ctx->writeCipher.sequenceNum;
+
+ if (ctx->protocolSide == SSL_ServerSide)
+ { writeKey = keyData.data;
+ readKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
+ }
+ else
+ { readKey = keyData.data;
+ writeKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
+ }
+
+ iv = ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize;
+
+ if ((err = ctx->readPending.symCipher->initialize(readKey, iv,
+ &ctx->readPending, ctx)) != 0 ||
+ (err = ctx->writePending.symCipher->initialize(writeKey, iv,
+ &ctx->writePending, ctx)) != 0)
+ { SSLFreeBuffer(keyData, ctx);
+ return err;
+ }
+
+ /*
+ * HEY! macSecret is only 20 bytes. This blows up when key size
+ * is greater than 20, e.g., 3DES.
+ * I'll increase the size of macSecret to 24, 'cause it appears
+ * from the SSL v23 spec that the macSecret really the same size as
+ * CLIENT-WRITE-KEY and SERVER-READ-KEY (see 1.2 of the spec).
+ */
+ memcpy(ctx->readPending.macSecret, readKey, ctx->selectedCipherSpec->cipher->keySize);
+ memcpy(ctx->writePending.macSecret, writeKey, ctx->selectedCipherSpec->cipher->keySize);
+
+ if ((err = SSLFreeBuffer(keyData, ctx)) != 0)
+ return err;
+
+ ctx->readCipher = ctx->readPending;
+ ctx->writeCipher = ctx->writePending;
+ memset(&ctx->readPending, 0, sizeof(CipherContext)); /* Zero out old data */
+ memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
+
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: ssl2Record.cpp
+
+ Contains: Record encrypting/decrypting/MACing for SSL 2
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl2.h"
+#include "sslRecord.h"
+#include "sslMemory.h"
+#include "sslContext.h"
+#include "sslAlertMessage.h"
+#include "sslDebug.h"
+#include "sslUtils.h"
+#include "sslDigests.h"
+
+#include <string.h>
+
+static OSStatus SSL2DecryptRecord(
+ SSLBuffer &payload,
+ SSLContext *ctx);
+static OSStatus SSL2VerifyMAC(
+ SSLBuffer &content,
+ UInt8 *compareMAC,
+ SSLContext *ctx);
+static OSStatus SSL2CalculateMAC(
+ SSLBuffer &secret,
+ SSLBuffer &content,
+ UInt32 seqNo,
+ const HashReference &hash,
+ SSLBuffer &mac,
+ SSLContext *ctx);
+
+
+OSStatus
+SSL2ReadRecord(SSLRecord &rec, SSLContext *ctx)
+{ OSStatus err;
+ UInt32 len, contentLen;
+ int padding, headerSize;
+ UInt8 *charPtr;
+ SSLBuffer readData, cipherFragment;
+
+ switch (ctx->negProtocolVersion)
+ { case SSL_Version_Undetermined:
+ case SSL_Version_3_0_With_2_0_Hello:
+ case SSL_Version_2_0:
+ break;
+ case SSL_Version_3_0: /* We've negotiated a 3.0 session;
+ * we can send an alert */
+ case TLS_Version_1_0:
+ SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ return errSSLProtocol;
+ case SSL_Version_3_0_Only: /* We haven't yet negotiated, but
+ * we don't want to support 2.0; just
+ * die without an alert */
+ return errSSLProtocol;
+ default:
+ sslErrorLog("bad protocolVersion in ctx->protocolVersion");
+ return errSSLInternal;
+ }
+
+ if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < 3)
+ { if (ctx->partialReadBuffer.data)
+ if ((err = SSLFreeBuffer(ctx->partialReadBuffer, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ if ((err = SSLAllocBuffer(ctx->partialReadBuffer, DEFAULT_BUFFER_SIZE, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+
+ if (ctx->amountRead < 3)
+ { readData.length = 3 - ctx->amountRead;
+ readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+ len = readData.length;
+ err = sslIoRead(readData, &len, ctx);
+ if(err != 0)
+ { if (err == errSSLWouldBlock)
+ ctx->amountRead += len;
+ if (err == ioErr && ctx->amountRead == 0) /* If the session closes on a record boundary, it's graceful */
+ err = errSSLClosedGraceful;
+ return err;
+ }
+ ctx->amountRead += len;
+ }
+
+ rec.contentType = SSL_RecordTypeV2_0;
+ rec.protocolVersion = SSL_Version_2_0;
+ charPtr = ctx->partialReadBuffer.data;
+
+ if (((*charPtr) & 0x80) != 0) /* High bit on -> specifies 2-byte header */
+ { headerSize = 2;
+ contentLen = ((charPtr[0] & 0x7F) << 8) | charPtr[1];
+ padding = 0;
+ }
+ else if (((*charPtr) & 0x40) != 0) /* Bit 6 on -> specifies security escape */
+ { return errSSLProtocol; /* No security escapes are defined */
+ }
+ else /* 3-byte header */
+ { headerSize = 3;
+ contentLen = ((charPtr[0] & 0x3F) << 8) | charPtr[1];
+ padding = charPtr[2];
+ }
+
+ /*
+ * FIXME - what's the max record size?
+ * and why doesn't SSLReadRecord parse the 2 or 3 byte header?
+ * Note: I see contentLen of 0 coming back from www.cduniverse.com when
+ * it's only been given SSL_RSA_EXPORT_WITH_DES40_CBC_SHA.
+ */
+ if((contentLen == 0) || (contentLen > 0xffff)) {
+ return errSSLProtocol;
+ }
+
+ charPtr += headerSize;
+
+ if (ctx->partialReadBuffer.length < headerSize + contentLen)
+ { if ((err = SSLReallocBuffer(ctx->partialReadBuffer, 5 + contentLen, ctx)) != 0)
+ return err;
+ }
+
+ if (ctx->amountRead < headerSize + contentLen)
+ { readData.length = headerSize + contentLen - ctx->amountRead;
+ readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+ len = readData.length;
+ err = sslIoRead(readData, &len, ctx);
+ if(err != 0)
+ { if (err == errSSLWouldBlock)
+ ctx->amountRead += len;
+ return err;
+ }
+ ctx->amountRead += len;
+ }
+
+ cipherFragment.data = ctx->partialReadBuffer.data + headerSize;
+ cipherFragment.length = contentLen;
+ if ((err = SSL2DecryptRecord(cipherFragment, ctx)) != 0)
+ return err;
+
+ cipherFragment.length -= padding; /* Remove padding; MAC was removed
+ * by SSL2DecryptRecord */
+
+ IncrementUInt64(&ctx->readCipher.sequenceNum);
+
+ /* Allocate a buffer to return the plaintext in and return it */
+ if ((err = SSLAllocBuffer(rec.contents, cipherFragment.length, ctx)) != 0)
+ return err;
+ memcpy(rec.contents.data, cipherFragment.data, cipherFragment.length);
+
+ ctx->amountRead = 0; /* We've used all the data in the cache */
+
+ return noErr;
+}
+
+OSStatus
+SSL2WriteRecord(SSLRecord &rec, SSLContext *ctx)
+{ OSStatus err;
+ int padding = 0, i, headerSize;
+ WaitingRecord *out, *queue;
+ SSLBuffer buf, content, payload, secret, mac;
+ UInt8 *charPtr;
+ UInt16 payloadSize, blockSize;
+
+ assert(rec.contents.length < 16384);
+
+ out = 0;
+ /* Allocate a WaitingRecord to store our ready-to-send record in */
+ if ((err = SSLAllocBuffer(buf, sizeof(WaitingRecord), ctx)) != 0)
+ return err;
+ out = (WaitingRecord*)buf.data;
+ out->next = 0;
+ out->sent = 0;
+
+ payloadSize = (UInt16)
+ (rec.contents.length + ctx->writeCipher.macRef->hash->digestSize);
+ blockSize = ctx->writeCipher.symCipher->blockSize;
+ if (blockSize > 0)
+ {
+ padding = blockSize - (payloadSize % blockSize);
+ if (padding == blockSize)
+ padding = 0;
+ payloadSize += padding;
+ headerSize = 3;
+ }
+ else
+ { padding = 0;
+ headerSize = 2;
+ }
+ out->data.data = 0;
+ if ((err = SSLAllocBuffer(out->data, headerSize + payloadSize, ctx)) != 0)
+ goto fail;
+ charPtr = out->data.data;
+
+ if (headerSize == 2)
+ charPtr = SSLEncodeInt(charPtr, payloadSize | 0x8000, 2);
+ else
+ { charPtr = SSLEncodeInt(charPtr, payloadSize, 2);
+ *charPtr++ = padding;
+ }
+
+ payload.data = charPtr;
+ payload.length = payloadSize;
+
+ mac.data = charPtr;
+ mac.length = ctx->writeCipher.macRef->hash->digestSize;
+ charPtr += mac.length;
+
+ content.data = charPtr;
+ content.length = rec.contents.length + padding;
+ memcpy(charPtr, rec.contents.data, rec.contents.length);
+ charPtr += rec.contents.length;
+ i = padding;
+ while (i--)
+ *charPtr++ = padding;
+
+ assert(charPtr == out->data.data + out->data.length);
+
+ secret.data = ctx->writeCipher.macSecret;
+ secret.length = ctx->writeCipher.symCipher->keySize;
+ if (mac.length > 0)
+ if ((err = SSL2CalculateMAC(secret, content,
+ ctx->writeCipher.sequenceNum.low,
+ *ctx->writeCipher.macRef->hash, mac, ctx)) != 0)
+ goto fail;
+
+ if ((err = ctx->writeCipher.symCipher->encrypt(payload,
+ payload,
+ &ctx->writeCipher,
+ ctx)) != 0)
+ goto fail;
+
+ /* Enqueue the record to be written from the idle loop */
+ if (ctx->recordWriteQueue == 0)
+ ctx->recordWriteQueue = out;
+ else
+ { queue = ctx->recordWriteQueue;
+ while (queue->next != 0)
+ queue = queue->next;
+ queue->next = out;
+ }
+
+ /* Increment the sequence number */
+ IncrementUInt64(&ctx->writeCipher.sequenceNum);
+
+ return noErr;
+
+fail:
+ /*
+ * Only for if we fail between when the WaitingRecord is allocated and
+ * when it is queued
+ */
+ SSLFreeBuffer(out->data, 0);
+ buf.data = (UInt8*)out;
+ buf.length = sizeof(WaitingRecord);
+ SSLFreeBuffer(buf, ctx);
+ return err;
+}
+
+static OSStatus
+SSL2DecryptRecord(SSLBuffer &payload, SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer content;
+
+ if (ctx->readCipher.symCipher->blockSize > 0)
+ if (payload.length % ctx->readCipher.symCipher->blockSize != 0)
+ return errSSLProtocol;
+
+ /* Decrypt in place */
+ if ((err = ctx->readCipher.symCipher->decrypt(payload,
+ payload,
+ &ctx->readCipher,
+ ctx)) != 0)
+ return err;
+
+ if (ctx->readCipher.macRef->hash->digestSize > 0)
+ /* Optimize away MAC for null case */
+ { content.data = payload.data + ctx->readCipher.macRef->hash->digestSize; /* Data is after MAC */
+ content.length = payload.length - ctx->readCipher.macRef->hash->digestSize;
+ if ((err = SSL2VerifyMAC(content, payload.data, ctx)) != 0)
+ return err;
+ /* Adjust payload to remove MAC; caller is still responsible
+ * for removing padding [if any] */
+ payload = content;
+ }
+
+ return noErr;
+}
+
+#define IGNORE_MAC_FAILURE 0
+
+static OSStatus
+SSL2VerifyMAC(SSLBuffer &content, UInt8 *compareMAC, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 calculatedMAC[SSL_MAX_DIGEST_LEN];
+ SSLBuffer secret, mac;
+
+ secret.data = ctx->readCipher.macSecret;
+ secret.length = ctx->readCipher.symCipher->keySize;
+ mac.data = calculatedMAC;
+ mac.length = ctx->readCipher.macRef->hash->digestSize;
+ if ((err = SSL2CalculateMAC(secret, content, ctx->readCipher.sequenceNum.low,
+ *ctx->readCipher.macRef->hash, mac, ctx)) != 0)
+ return err;
+ if (memcmp(mac.data, compareMAC, mac.length) != 0) {
+ #if IGNORE_MAC_FAILURE
+ sslErrorLog("SSL2VerifyMAC: Mac verify failure\n");
+ return noErr;
+ #else
+ sslErrorLog("SSL2VerifyMAC: Mac verify failure\n");
+ return errSSLProtocol;
+ #endif
+ }
+ return noErr;
+}
+
+#define LOG_MAC_DATA 0
+#if LOG_MAC_DATA
+static void logMacData(
+ char *field,
+ SSLBuffer *data)
+{
+ int i;
+
+ printf("%s: ", field);
+ for(i=0; i<data->length; i++) {
+ printf("%02X", data->data[i]);
+ if((i % 4) == 3) {
+ printf(" ");
+ }
+ }
+ printf("\n");
+}
+#else /* LOG_MAC_DATA */
+#define logMacData(f, d)
+#endif /* LOG_MAC_DATA */
+
+/* For SSL 2, the MAC is hash ( secret || content || sequence# )
+ * where secret is the decryption key for the message, content is
+ * the record data plus any padding used to round out the record
+ * size to an even multiple of the block size and sequence# is
+ * a monotonically increasing 32-bit unsigned integer.
+ */
+static OSStatus
+SSL2CalculateMAC(
+ SSLBuffer &secret,
+ SSLBuffer &content,
+ UInt32 seqNo,
+ const HashReference &hash,
+ SSLBuffer &mac,
+ SSLContext *ctx)
+{ OSStatus err;
+ UInt8 sequenceNum[4];
+ SSLBuffer seqData, hashContext;
+
+ SSLEncodeInt(sequenceNum, seqNo, 4);
+ seqData.data = sequenceNum;
+ seqData.length = 4;
+
+ hashContext.data = 0;
+ if ((err = ReadyHash(hash, hashContext, ctx)) != 0)
+ return err;
+ if ((err = hash.update(hashContext, secret)) != 0)
+ goto fail;
+ if ((err = hash.update(hashContext, content)) != 0)
+ goto fail;
+ if ((err = hash.update(hashContext, seqData)) != 0)
+ goto fail;
+ if ((err = hash.final(hashContext, mac)) != 0)
+ goto fail;
+
+ logMacData("secret ", &secret);
+ logMacData("seqData", &seqData);
+ logMacData("mac ", &mac);
+
+ err = noErr;
+fail:
+ SSLFreeBuffer(hashContext, ctx);
+ return err;
+}
+
+OSStatus
+SSL2SendError(SSL2ErrorCode error, SSLContext *ctx)
+{ OSStatus err;
+ SSLRecord rec;
+ UInt8 errorData[3];
+
+ rec.contentType = SSL_RecordTypeV2_0;
+ rec.protocolVersion = SSL_Version_2_0;
+ rec.contents.data = errorData;
+ rec.contents.length = 3;
+ errorData[0] = SSL2_MsgError;
+ SSLEncodeInt(errorData + 1, error, 2);
+
+ err = SSL2WriteRecord(rec, ctx);
+ return err;
+}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: ssl2map.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ssl2map.c Maps SSL 2 cipher kinds to SSL 3 cipher suites
-
- We use the SSL 3 CipherSuites to look up ciphers, hashes, etc; thus,
- this table maps two-byte SSL 3 CipherSuite values to three-byte SSL 2
- CipherKind values.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _CRYPTTYPE_H_
-#include "cryptType.h"
-#endif
-
-const SSLCipherMapping SSL2CipherMap[] =
-{ { SSL2_RC4_128_WITH_MD5, SSL_RSA_WITH_RC4_128_MD5 },
- { SSL2_RC4_128_EXPORT_40_WITH_MD5, SSL_RSA_EXPORT_WITH_RC4_40_MD5 },
- { SSL2_RC2_128_CBC_WITH_MD5, SSL_RSA_WITH_RC2_CBC_MD5 },
- { SSL2_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 },
- { SSL2_IDEA_128_CBC_WITH_MD5, SSL_RSA_WITH_IDEA_CBC_MD5 },
- { SSL2_DES_64_CBC_WITH_MD5, SSL_RSA_WITH_DES_CBC_MD5 },
- { SSL2_DES_192_EDE3_CBC_WITH_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5}
-};
-
-const int SSL2CipherMapCount = sizeof(SSL2CipherMap) / sizeof(SSLCipherMapping);
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: ssl2mesg.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ssl2mesg.c Message encoding and decoding functions for SSL 2
-
- The necessary message encoding and decoding for all SSL 2 handshake
- messages.
-
- ****************************************************************** */
-
-#ifndef _SSL_H_
-#include "ssl.h"
-#endif
-
-#ifndef _SSL2_H_
-#include "ssl2.h"
-#endif
-
-#ifndef _SSLREC_H_
-#include "sslrec.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLSESS_H_
-#include "sslsess.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _CIPHER_SPECS_H_
-#include "cipherSpecs.h"
-#endif
-
-#ifndef _APPLE_CDSA_H_
-#include "appleCdsa.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#include <string.h>
-#include <assert.h>
-
-SSLErr
-SSL2ProcessClientHello(SSLBuffer msg, SSLContext *ctx)
-{ SSLErr err;
- UInt8 *progress, *cipherList;
- int i, j, cipherKindCount, sessionIDLen, challengeLen;
- SSL2CipherKind cipherKind;
- SSLCipherSuite matchingCipher, selectedCipher;
- SSLProtocolVersion version;
-
- if (msg.length < 27) {
- errorLog0("SSL2ProcessClientHello: msg len error 1\n");
- return ERR(SSLProtocolErr);
- }
-
- progress = msg.data;
-
- version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
- if (version > ctx->maxProtocolVersion) {
- version = ctx->maxProtocolVersion;
- }
- /* FIXME - I think this needs work for a SSL_Version_2_0 server, to ensure that
- * the client isn't establishing a v3 session. */
- if (ctx->negProtocolVersion == SSL_Version_Undetermined)
- {
- #if LOG_NEGOTIATE
- dprintf1("===SSL2 server: negVersion was undetermined; is %s\n",
- protocolVersStr(version));
- #endif
- ctx->negProtocolVersion = version;
- if(version >= TLS_Version_1_0) {
- ctx->sslTslCalls = &Tls1Callouts;
- }
- else {
- /* default from context init */
- assert(ctx->sslTslCalls == &Ssl3Callouts);
- }
- }
- else if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
- { if (version < SSL_Version_3_0) {
- errorLog0("SSL2ProcessClientHello: version error\n");
- return ERR(SSLProtocolErr);
- }
- /* FIXME - I don't think path is ever taken - we NEVER set any
- * protocol var to SSL_Version_3_0_With_2_0_Hello... */
- #if LOG_NEGOTIATE
- dprintf0("===SSL2 server: negVersion was 3_0_With_2_0_Hello; is 3_0\n");
- #endif
- ctx->negProtocolVersion = version;
- }
-
- progress += 2;
- cipherKindCount = SSLDecodeInt(progress, 2);
- progress += 2;
- if (cipherKindCount % 3 != 0) {
- errorLog0("SSL2ProcessClientHello: cipherKindCount error\n");
- return ERR(SSLProtocolErr);
- }
- cipherKindCount /= 3;
- sessionIDLen = SSLDecodeInt(progress, 2);
- progress += 2;
- challengeLen = SSLDecodeInt(progress, 2);
- progress += 2;
-
- if (msg.length != 8 + 3*cipherKindCount + sessionIDLen + challengeLen ||
- (sessionIDLen != 0 && sessionIDLen != 16) ||
- challengeLen < 16 || challengeLen > 32 ) {
- errorLog0("SSL2ProcessClientHello: msg len error 2\n");
- return ERR(SSLProtocolErr);
- }
- cipherList = progress;
- selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
-
- if (ctx->negProtocolVersion >= SSL_Version_3_0) {
- /* If we're negotiating an SSL 3.0 session, use SSL 3.0 suites first */
- for (i = 0; i < cipherKindCount; i++) {
- cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
- progress += 3;
- if (selectedCipher != SSL_NO_SUCH_CIPHERSUITE)
- continue;
- if ((((UInt32)cipherKind) & 0xFF0000) != 0)
- continue; /* Skip SSL 2 suites */
- matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
- for (j = 0; j<ctx->numValidCipherSpecs; j++) {
- if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher) {
- selectedCipher = matchingCipher;
- break;
- }
- } /* searching thru all our valid ciphers */
- } /* for each client cipher */
- } /* v3 or greater */
-
- if(selectedCipher == SSL_NO_SUCH_CIPHERSUITE) {
- /* try again using SSL2 ciphers only */
- progress = cipherList;
- for (i = 0; i < cipherKindCount; i++) {
- cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
- progress += 3;
- if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) {
- /* After we find one, just keep advancing progress past
- * the unused ones */
- if ((((UInt32)cipherKind) & 0xFF0000) != 0) {
- /* If it's a real SSL2 spec, look for it in the list */
- matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
- for (j = 0; j < SSL2CipherMapCount; j++) {
- if (cipherKind == SSL2CipherMap[j].cipherKind) {
- matchingCipher = SSL2CipherMap[j].cipherSuite;
- break;
- }
- }
- } /* real 3-byte SSL2 suite */
- else {
- /* if the first byte is zero, it's an encoded SSL 3 CipherSuite */
- matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
- /*
- * One more restriction - if we've negotiated a v2 session,
- * ignore this matching cipher if it's not in the SSL2 map.
- */
- if(ctx->negProtocolVersion < SSL_Version_3_0) {
- int isInMap = 0;
- for (j = 0; j < SSL2CipherMapCount; j++) {
- if (matchingCipher == SSL2CipherMap[j].cipherSuite) {
- isInMap = 1;
- break;
- }
- }
- if(!isInMap) {
- /* Sorry, no can do */
- matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
- }
- } /* SSL2 check */
- } /* two-byte suite */
-
- /* now see if we are enabled for this cipher */
- if (matchingCipher != SSL_NO_SUCH_CIPHERSUITE) {
- for (j = 0; j < ctx->numValidCipherSpecs; j++) {
- if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher) {
- selectedCipher = matchingCipher;
- break;
- }
- }
- }
- } /* not ignoring this suite */
- } /* for each suite in the hello msg */
- } /* not found in SSL3 ciphersuites */
-
- if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
- return ERR(SSLNegotiationErr);
-
- ctx->selectedCipher = selectedCipher;
- err = FindCipherSpec(ctx);
- if(err != 0) {
- return err;
- }
- if (sessionIDLen > 0 && ctx->peerID.data != 0)
- { /* Don't die on error; just treat it as an uncacheable session */
- ERR(err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx));
- if (err == 0)
- memcpy(ctx->sessionID.data, progress, sessionIDLen);
- }
- progress += sessionIDLen;
-
- ctx->ssl2ChallengeLength = challengeLen;
- memset(ctx->clientRandom, 0, SSL_CLIENT_SRVR_RAND_SIZE);
- memcpy(ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE - challengeLen,
- progress, challengeLen);
- progress += challengeLen;
- CASSERT(progress == msg.data + msg.length);
-
- return SSLNoErr;
-}
-
-/*
- * The SSL v2 spec says that the challenge string sent by the client can be
- * between 16 and 32 bytes. However all Netscape enterprise servers actually
- * require a 16 byte challenge. Q.v. cdnow.com, store.apple.com.
- * Unfortunately this means that when we're trying to do a
- * SSL_Version_3_0_With_2_0_Hello negotiation, we have to limit ourself to
- * a 16-byte clientRandom, which we have to concatenate to 16 bytes of
- * zeroes if we end up with a 3.0 or 3.1 connection. Thus we lose 16 bytes
- * of entropy.
- */
-#define SSL2_CHALLENGE_LEN 16
-
-SSLErr
-SSL2EncodeClientHello(SSLBuffer *msg, SSLContext *ctx)
-{ SSLErr err;
- UInt8 *progress;
- int i, j, useSSL3Ciphers, totalCipherCount;
- int sessionIDLen;
- UInt16 version;
- SSLBuffer sessionIdentifier, randomData;
-
- switch (ctx->negProtocolVersion)
- { case SSL_Version_Undetermined:
- case SSL_Version_3_0_With_2_0_Hello:
- /* go for it, see if server can handle upgrading */
- useSSL3Ciphers = 1;
- /* could be SSLv3 or TLSv1 */
- version = ctx->maxProtocolVersion;
- break;
- case SSL_Version_2_0:
- useSSL3Ciphers = 0;
- version = SSL_Version_2_0;
- break;
- case SSL_Version_3_0_Only:
- case SSL_Version_3_0:
- case TLS_Version_1_0_Only:
- case TLS_Version_1_0:
- default:
- ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
- break;
- }
- #if LOG_NEGOTIATE
- dprintf1("===SSL client: proclaiming %s capable\n",
- protocolVersStr((SSLProtocolVersion)version));
- #endif
-
- if (useSSL3Ciphers != 0)
- totalCipherCount = ctx->numValidCipherSpecs;
- else
- totalCipherCount = 0;
-
- for (i = 0; i < SSL2CipherMapCount; i++)
- for (j = 0; j < ctx->numValidCipherSpecs; j++)
- if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
- { totalCipherCount++;
- break;
- }
-
- sessionIDLen = 0;
- sessionIdentifier.data = 0;
- if (ctx->resumableSession.data != 0)
- { if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
- return err;
- sessionIDLen = sessionIdentifier.length;
- }
-
- /* msg length = 9 + 3 * totalCipherCount + sessionIDLen + 16 bytes of challenge
- * Use exactly 16 bytes of challenge because Netscape products have a bug
- * that requires this length
- */
- if (ERR(err = SSLAllocBuffer(msg, 9 + (3*totalCipherCount) + sessionIDLen +
- SSL2_CHALLENGE_LEN, &ctx->sysCtx)) != 0)
- { ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
- return err;
- }
-
- progress = msg->data;
- *progress++ = ssl2_mt_client_hello;
- progress = SSLEncodeInt(progress, version, 2);
- progress = SSLEncodeInt(progress, 3*totalCipherCount, 2);
- progress = SSLEncodeInt(progress, sessionIDLen, 2);
- progress = SSLEncodeInt(progress, SSL2_CHALLENGE_LEN, 2);
-
- /* If we can send SSL3 ciphers, encode the two-byte cipher specs into three-byte
- * CipherKinds which have a leading 0.
- */
- if (useSSL3Ciphers != 0)
- for (i = 0; i < ctx->numValidCipherSpecs; i++)
- progress = SSLEncodeInt(progress, ctx->validCipherSpecs[i].cipherSpec, 3);
-
- /* Now send those SSL2 specs for which we have implementations */
- for (i = 0; i < SSL2CipherMapCount; i++)
- for (j = 0; j < ctx->numValidCipherSpecs; j++)
- if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
- { progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
- break;
- }
-
- if (sessionIDLen > 0)
- { memcpy(progress, sessionIdentifier.data, sessionIDLen);
- progress += sessionIDLen;
- ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
- }
-
- randomData.data = progress;
- randomData.length = SSL2_CHALLENGE_LEN;
- if ((err = sslRand(ctx, &randomData)) != 0)
- { ERR(SSLFreeBuffer(msg, &ctx->sysCtx));
- return err;
- }
- progress += SSL2_CHALLENGE_LEN;
-
- /* Zero out the first 16 bytes of clientRandom, and store
- * the challenge in the second 16 bytes */
- #if (SSL2_CHALLENGE_LEN == SSL_CLIENT_SRVR_RAND_SIZE)
- /* this path verified to fail with Netscape Enterprise servers 1/16/02 */
- memcpy(ctx->clientRandom, randomData.data, SSL2_CHALLENGE_LEN);
- #else
- memset(ctx->clientRandom, 0, SSL_CLIENT_SRVR_RAND_SIZE - SSL2_CHALLENGE_LEN);
- memcpy(ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE - SSL2_CHALLENGE_LEN,
- randomData.data, SSL2_CHALLENGE_LEN);
- #endif
- ctx->ssl2ChallengeLength = SSL2_CHALLENGE_LEN;
-
- CASSERT(progress == msg->data + msg->length);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2ProcessClientMasterKey(SSLBuffer msg, SSLContext *ctx)
-{ SSLErr err;
- SSL2CipherKind cipherKind;
- SSLBuffer secretData;
- int clearLength, encryptedLength, keyArgLength;
- UInt32 secretLength, localKeyModulusLen;
- UInt8 *progress;
- const CSSM_KEY *decryptKey;
- CSSM_CSP_HANDLE decryptCspHand;
-
- if (msg.length < 9) {
- errorLog0("SSL2ProcessClientMasterKey: msg.length error 1\n");
- return ERR(SSLProtocolErr);
- }
- CASSERT(ctx->protocolSide == SSL_ServerSide);
-
- progress = msg.data;
- cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
- progress += 3;
- clearLength = SSLDecodeInt(progress, 2);
- progress += 2;
- encryptedLength = SSLDecodeInt(progress, 2);
- progress += 2;
- keyArgLength = SSLDecodeInt(progress, 2);
- progress += 2;
-
- if (msg.length != 9 + clearLength + encryptedLength + keyArgLength) {
- errorLog0("SSL2ProcessClientMasterKey: msg.length error 2\n");
- return ERR(SSLProtocolErr);
- }
-
- /* Master key == CLEAR_DATA || SECRET_DATA */
- memcpy(ctx->masterSecret, progress, clearLength);
- progress += clearLength;
-
- /*
- * Just as in SSL2EncodeServerHello, which key we use depends on the
- * app's config.
- */
- if(ctx->encryptPrivKey) {
- decryptKey = ctx->encryptPrivKey;
- CASSERT(ctx->encryptKeyCsp != 0);
- decryptCspHand = ctx->encryptKeyCsp;
- }
- else if(ctx->signingPrivKey) {
- decryptKey = ctx->signingPrivKey;
- CASSERT(ctx->signingKeyCsp != 0);
- decryptCspHand = ctx->signingKeyCsp;
- }
- else {
- /* really should not happen... */
- errorLog0("SSL2ProcessClientMasterKey: No server key!\n");
- return SSLBadStateErr;
- }
- localKeyModulusLen = sslKeyLengthInBytes(decryptKey);
-
- if (encryptedLength != localKeyModulusLen) {
- errorLog0("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
- return ERR(SSLProtocolErr);
- }
-
- /* Allocate enough room to hold any decrypted value */
- if (ERR(err = SSLAllocBuffer(&secretData, encryptedLength, &ctx->sysCtx)) != 0)
- return err;
-
- err = sslRsaDecrypt(ctx,
- decryptKey,
- decryptCspHand,
- progress,
- encryptedLength,
- secretData.data,
- encryptedLength, // same length for both...?
- &secretLength);
- if(err) {
- SSLFreeBuffer(&secretData, &ctx->sysCtx);
- return err;
- }
-
- progress += encryptedLength;
-
- if (clearLength + secretLength != ctx->selectedCipherSpec->cipher->keySize) {
- errorLog0("SSL2ProcessClientMasterKey: length error 3\n");
- return ERR(SSLProtocolErr);
- }
- memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
- if (ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx)) != 0)
- return err;
-
- if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize) {
- errorLog0("SSL2ProcessClientMasterKey: length error 4\n");
- return ERR(SSLProtocolErr);
- }
-
- /* Stash the IV after the master key in master secret storage */
- memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, progress, keyArgLength);
- progress += keyArgLength;
- CASSERT(progress = msg.data + msg.length);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx)
-{ SSLErr err;
- int length, i, clearLen;
- UInt32 outputLen, peerKeyModulusLen;
- SSLBuffer keyData;
- UInt8 *progress;
-
- peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
-
- /* Length is 10 + clear key size + encrypted output size + iv size */
- length = 10;
- clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
- length += clearLen;
- length += peerKeyModulusLen;
- length += ctx->selectedCipherSpec->cipher->ivSize;
-
- if (ERR(err = SSLAllocBuffer(msg, length, &ctx->sysCtx)) != 0)
- return err;
- progress = msg->data;
- *progress++ = ssl2_mt_client_master_key;
- for (i = 0; i < SSL2CipherMapCount; i++)
- if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
- break;
- CASSERT(i < SSL2CipherMapCount);
- #if LOG_NEGOTIATE
- dprintf1("===SSL2EncodeClientMasterKey: sending cipherKind 0x%x\n",
- SSL2CipherMap[i].cipherKind);
- #endif
- progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
- progress = SSLEncodeInt(progress, clearLen, 2);
- progress = SSLEncodeInt(progress, peerKeyModulusLen, 2);
- progress = SSLEncodeInt(progress, ctx->selectedCipherSpec->cipher->ivSize, 2);
-
- /* Generate the keying material; we need enough data for the key and IV */
- keyData.data = ctx->masterSecret;
- keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
- CASSERT(keyData.length <= 48); /* Must be able to store it in the masterSecret array */
- if ((err = sslRand(ctx, &keyData)) != 0)
- return err;
-
- memcpy(progress, ctx->masterSecret, clearLen);
- progress += clearLen;
-
- /* Replace this with code to do encryption at lower level & set PKCS1 padding
- for rollback attack */
-
- /*
- * encrypt only the secret key portion of masterSecret, starting at
- * clearLen bytes
- */
- err = sslRsaEncrypt(ctx,
- ctx->peerPubKey,
- ctx->peerPubKeyCsp, // XX - maybe cspHand
- ctx->masterSecret + clearLen,
- ctx->selectedCipherSpec->cipher->keySize - clearLen,
- progress,
- peerKeyModulusLen,
- &outputLen);
- if(err) {
- return err;
- }
-
- progress += outputLen;
-
- /* copy clear IV to msg buf */
- memcpy(progress, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
- ctx->selectedCipherSpec->cipher->ivSize);
- progress += ctx->selectedCipherSpec->cipher->ivSize;
-
- CASSERT(progress == msg->data + msg->length);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
-{ if (msg.length != ctx->sessionID.length) {
- errorLog0("SSL2ProcessClientFinished: length error\n");
- return ERR(SSLProtocolErr);
- }
- if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0) {
- errorLog0("SSL2ProcessClientFinished: data compare error\n");
- return ERR(SSLProtocolErr);
- }
- return SSLNoErr;
-}
-
-SSLErr
-SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx)
-{ SSLErr err;
-
- if (ERR(err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, &ctx->sysCtx)) != 0)
- return err;
- msg->data[0] = ssl2_mt_client_finished;
- memcpy(msg->data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
- return SSLNoErr;
-}
-
-SSLErr
-SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
-{ SSLErr err;
- SSL2CertTypeCode certType;
- int sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
- int i, j;
- SSL2CipherKind cipherKind;
- SSLCertificate *cert;
- SSLCipherSuite matchingCipher = 0; // avoid compiler warning
- SSLCipherSuite selectedCipher;
- UInt8 *progress;
- SSLProtocolVersion version;
-
- if (msg.length < 10) {
- errorLog0("SSL2ProcessServerHello: length error\n");
- return ERR(SSLProtocolErr);
- }
- progress = msg.data;
-
- sessionIDMatch = *progress++;
- certType = (SSL2CertTypeCode)*progress++;
- version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
- progress += 2;
- if (version != SSL_Version_2_0) {
- errorLog0("SSL2ProcessServerHello: version error\n");
- return ERR(SSLProtocolErr);
- }
- ctx->negProtocolVersion = version;
- #if LOG_NEGOTIATE
- dprintf0("===SSL2 client: negVersion is 2_0\n");
- #endif
- certLen = SSLDecodeInt(progress, 2);
- progress += 2;
- cipherSpecsLen = SSLDecodeInt(progress, 2);
- progress += 2;
- connectionIDLen = SSLDecodeInt(progress, 2);
- progress += 2;
-
- if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
- (msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
- return ERR(SSLProtocolErr);
- if (sessionIDMatch != 0)
- { if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
- return ERR(SSLProtocolErr);
- ctx->ssl2SessionMatch = 1;
-
- ctx->ssl2ConnectionIDLength = connectionIDLen;
- memcpy(ctx->serverRandom, progress, connectionIDLen);
- progress += connectionIDLen;
- }
- else
- { if (certType != ssl2_ct_x509_certificate)
- return ERR(SSLNegotiationErr);
- cipherSpecsLen /= 3;
-
- cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
- if(cert == NULL) {
- return SSLMemoryErr;
- }
- cert->next = 0;
- if (ERR(err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
- {
- sslFree(cert);
- return err;
- }
- memcpy(cert->derCert.data, progress, certLen);
- progress += certLen;
- ctx->peerCert = cert;
- /* This cert never gets verified in original SSLRef3 code... */
- if((err = sslVerifyCertChain(ctx, ctx->peerCert)) != 0) {
- return err;
- }
- if((err = sslPubKeyFromCert(ctx,
- &cert->derCert,
- &ctx->peerPubKey,
- &ctx->peerPubKeyCsp)) != 0)
- return err;
-
- selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
- for (i = 0; i < cipherSpecsLen; i++)
- { cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
- progress += 3;
- //dprintf1("ssl2: server supports cipherKind 0x%x\n", (UInt32)cipherKind);
- if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) /* After we find one, just keep advancing progress past the unused ones */
- { for (j = 0; j < SSL2CipherMapCount; j++)
- if (cipherKind == SSL2CipherMap[j].cipherKind)
- { matchingCipher = SSL2CipherMap[j].cipherSuite;
- break;
- }
- for (j = 0; j < ctx->numValidCipherSpecs; j++)
- if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
- { selectedCipher = matchingCipher;
- break;
- }
- }
- }
- if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
- return ERR(SSLNegotiationErr);
- #if LOG_NEGOTIATE
- dprintf1("===SSL2 client: selectedCipher 0x%x\n",
- (unsigned)selectedCipher);
- #endif
-
- ctx->selectedCipher = selectedCipher;
- if (ERR(err = FindCipherSpec(ctx)) != 0) {
- return err;
- }
- ctx->ssl2ConnectionIDLength = connectionIDLen;
- memcpy(ctx->serverRandom, progress, connectionIDLen);
- progress += connectionIDLen;
- }
-
- CASSERT(progress == msg.data + msg.length);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx)
-{ SSLErr err;
- SSLCertificate *cert;
- SSLBuffer randomData;
- UInt8 *progress;
- int i;
-
- /* Create the connection ID */
- ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
- randomData.data = ctx->serverRandom;
- randomData.length = ctx->ssl2ConnectionIDLength;
- if ((err = sslRand(ctx, &randomData)) != 0)
- return err;
-
- if (ctx->ssl2SessionMatch != 0)
- { if (ERR(err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
- return err;
- progress = msg->data;
- *progress++ = ssl2_mt_server_hello;
- *progress++ = ctx->ssl2SessionMatch;
- *progress++ = 0; /* cert type */
- progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
- progress = SSLEncodeInt(progress, 0, 2); /* cert len */
- progress = SSLEncodeInt(progress, 0, 2); /* cipherspecs len */
- progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
- memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
- progress += ctx->ssl2ConnectionIDLength;
- }
- else
- { /* First, find the last cert in the chain; it's the one we'll send */
-
- /*
- * Use encryptCert if we have it, but allow for the case of app
- * specifying one cert which can encrypt and sign.
- */
- if(ctx->encryptCert != NULL) {
- cert = ctx->encryptCert;
- }
- else if(ctx->localCert != NULL) {
- cert = ctx->localCert;
- }
- else {
- /* really should not happen... */
- errorLog0("SSL2EncodeServerHello: No server cert!\n");
- return SSLBadStateErr;
- }
-
- while (cert->next != 0)
- cert = cert->next;
-
- if (ERR(err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
- return err;
- progress = msg->data;
- *progress++ = ssl2_mt_server_hello;
- *progress++ = ctx->ssl2SessionMatch;
- *progress++ = ssl2_ct_x509_certificate; /* cert type */
- #if LOG_NEGOTIATE
- dprintf1("===SSL2 server: sending vers info %s\n",
- protocolVersStr((SSLProtocolVersion)ctx->negProtocolVersion));
- #endif
- progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
- progress = SSLEncodeInt(progress, cert->derCert.length, 2);
- progress = SSLEncodeInt(progress, 3, 2); /* cipherspecs len */
- progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
- memcpy(progress, cert->derCert.data, cert->derCert.length);
- progress += cert->derCert.length;
- for (i = 0; i < SSL2CipherMapCount; i++)
- if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
- break;
- CASSERT(i < SSL2CipherMapCount);
- progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
- dprintf1("ssl2: server specifying cipherKind 0x%lx\n",
- (UInt32)SSL2CipherMap[i].cipherKind);
- memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
- progress += ctx->ssl2ConnectionIDLength;
- }
-
- CASSERT(progress == msg->data + msg->length);
- return SSLNoErr;
-}
-
-SSLErr
-SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
-{ if (msg.length != ctx->ssl2ChallengeLength)
- return ERR(SSLProtocolErr);
-
- if (memcmp(msg.data, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
- ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength) != 0)
- return ERR(SSLProtocolErr);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx)
-{ SSLErr err;
-
- if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, &ctx->sysCtx)) != 0)
- return err;
-
- msg->data[0] = ssl2_mt_server_verify;
- memcpy(msg->data+1, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
- ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength);
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
-{ SSLErr err;
-
- if (ERR(err = SSLAllocBuffer(&ctx->sessionID, msg.length, &ctx->sysCtx)) != 0)
- return err;
- memcpy(ctx->sessionID.data, msg.data, msg.length);
- return SSLNoErr;
-}
-
-SSLErr
-SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx)
-{ SSLErr err;
-
- if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
- return err;
-
- msg->data[0] = ssl2_mt_server_finished;
- memcpy(msg->data+1, ctx->sessionID.data, ctx->sessionID.length);
-
- return SSLNoErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: ssl2prot.c
-
- Contains: Protocol engine for SSL 2
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: ssl2prot.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ssl2prot.c Protocol engine for SSL 2
-
- This is the heart of the SSL 2 implementation, including the state
- engine for proceeding through the handshake and the necessary code
- for installing negotiated keys and algorithms.
-
- ****************************************************************** */
-
-#ifndef _SSL_H_
-#include "ssl.h"
-#endif
-
-#ifndef _SSL2_H_
-#include "ssl2.h"
-#endif
-
-#ifndef _SSLREC_H_
-#include "sslrec.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLSESS_H_
-#include "sslsess.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _APPLE_CDSA_H_
-#include "appleCdsa.h"
-#endif
-
-#include "digests.h"
-#include <string.h>
-#include <assert.h>
-
-#if LOG_HDSK_MSG
-
-static char *sslHdskMsgToStr(SSL2MessageType msg)
-{
- static char badStr[100];
-
- switch(msg) {
- case ssl2_mt_error:
- return "ssl2_mt_error";
- case ssl2_mt_client_hello:
- return "ssl2_mt_client_hello";
- case ssl2_mt_client_master_key:
- return "ssl2_mt_client_master_key";
- case ssl2_mt_client_finished:
- return "ssl2_mt_client_finished";
- case ssl2_mt_server_hello:
- return "ssl2_mt_server_hello";
- case ssl2_mt_server_verify:
- return "ssl2_mt_server_verify";
- case ssl2_mt_server_finished:
- return "ssl2_mt_server_finished";
- case ssl2_mt_request_certificate:
- return "ssl2_mt_request_certificate";
- case ssl2_mt_client_certificate:
- return "ssl2_mt_client_certificate";
- case ssl2_mt_kickstart_handshake:
- return "ssl2_mt_kickstart_handshake";
- default:
- sprintf(badStr, "Unknown msg (%d(d)", msg);
- return badStr;
- }
-}
-
-static void logSsl2Msg(SSL2MessageType msg, char sent)
-{
- char *ms = sslHdskMsgToStr(msg);
- printf("...msg %s: %s\n", (sent ? "sent" : "recd"), ms);
-}
-
-#else /* SSL_DEBUG */
-
-#define logSsl2Msg(m, s)
-
-#endif
-
-SSLErr
-SSL2ProcessMessage(SSLRecord rec, SSLContext *ctx)
-{ SSLErr err = 0;
- SSL2MessageType msg;
- SSLBuffer contents;
-
- if (rec.contents.length < 2)
- return ERR(SSLProtocolErr);
-
- msg = (SSL2MessageType)rec.contents.data[0];
- contents.data = rec.contents.data + 1;
- contents.length = rec.contents.length - 1;
-
- logSsl2Msg(msg, 0);
-
- switch (msg)
- { case ssl2_mt_error:
- err = SSLConnectionClosedError;
- break;
- case ssl2_mt_client_hello:
- if (ctx->state != HandshakeServerUninit)
- return ERR(SSLProtocolErr);
- ERR(err = SSL2ProcessClientHello(contents, ctx));
- if (err == SSLNegotiationErr)
- ERR(SSL2SendError(ssl2_pe_no_cipher, ctx));
- break;
- case ssl2_mt_client_master_key:
- if (ctx->state != HandshakeSSL2ClientMasterKey)
- return ERR(SSLProtocolErr);
- ERR(err = SSL2ProcessClientMasterKey(contents, ctx));
- break;
- case ssl2_mt_client_finished:
- if (ctx->state != HandshakeSSL2ClientFinished)
- return ERR(SSLProtocolErr);
- ERR(err = SSL2ProcessClientFinished(contents, ctx));
- break;
- case ssl2_mt_server_hello:
- if (ctx->state != HandshakeSSL2ServerHello &&
- ctx->state != HandshakeServerHelloUnknownVersion)
- return ERR(SSLProtocolErr);
- ERR(err = SSL2ProcessServerHello(contents, ctx));
- if (err == SSLNegotiationErr)
- ERR(SSL2SendError(ssl2_pe_no_cipher, ctx));
- break;
- case ssl2_mt_server_verify:
- if (ctx->state != HandshakeSSL2ServerVerify)
- return ERR(SSLProtocolErr);
- ERR(err = SSL2ProcessServerVerify(contents, ctx));
- break;
- case ssl2_mt_server_finished:
- if (ctx->state != HandshakeSSL2ServerFinished) {
- #if LOG_HDSK_STATE
- errorLog1("ssl2_mt_server_finished; state %s\n",
- hdskStateToStr(ctx->state));
- #endif
- return ERR(SSLProtocolErr);
- }
- ERR(err = SSL2ProcessServerFinished(contents, ctx));
- break;
- case ssl2_mt_request_certificate:
- /* Don't process the request; we don't support client certification */
- break;
- case ssl2_mt_client_certificate:
- return ERR(SSLProtocolErr);
- break;
- default:
- DEBUGVAL1("Unknown message %d", msg);
- return ERR(SSLProtocolErr);
- break;
- }
-
- if (err == 0)
- { /* FIXME - use requested or negotiated protocol version here? */
- if (msg == ssl2_mt_client_hello && (ctx->negProtocolVersion >= SSL_Version_3_0))
- { /* Promote this message to SSL 3 protocol */
- if (ERR(err = SSL3ReceiveSSL2ClientHello(rec, ctx)) != 0)
- return err;
- }
- else
- ERR(err = SSL2AdvanceHandshake(msg, ctx));
- }
- return err;
-}
-
-SSLErr
-SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx)
-{ SSLErr err;
-
- err = SSLNoErr;
-
- switch (msg)
- { case ssl2_mt_kickstart_handshake:
- if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
- ctx->negProtocolVersion == SSL_Version_Undetermined)
- if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
- return err;
- if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientHello, ctx)) != 0)
- return err;
- switch (ctx->negProtocolVersion)
- { case SSL_Version_Undetermined:
- SSLChangeHdskState(ctx, HandshakeServerHelloUnknownVersion);
- break;
- case SSL_Version_3_0_With_2_0_Hello:
- assert((ctx->reqProtocolVersion == SSL_Version_3_0) ||
- (ctx->reqProtocolVersion == TLS_Version_1_0));
- ctx->negProtocolVersion = ctx->reqProtocolVersion;
- #if LOG_NEGOTIATE
- dprintf2("===SSL client kickstart: negVersion is %d_%d\n",
- ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
- #endif
- SSLChangeHdskState(ctx, HandshakeServerHello);
- break;
- case SSL_Version_2_0:
- SSLChangeHdskState(ctx, HandshakeSSL2ServerHello);
- break;
- case SSL_Version_3_0_Only:
- case SSL_Version_3_0:
- case TLS_Version_1_0_Only:
- case TLS_Version_1_0:
- default:
- ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
- break;
- }
- break;
- case ssl2_mt_client_hello:
- if (ERR(err = SSL2CompareSessionIDs(ctx)) != 0)
- return err;
- if (ctx->ssl2SessionMatch == 0)
- if (ERR(err = SSL2GenerateSessionID(ctx)) != 0)
- return err;
- if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerHello, ctx)) != 0)
- return err;
- if (ctx->ssl2SessionMatch == 0)
- { SSLChangeHdskState(ctx, HandshakeSSL2ClientMasterKey);
- break;
- }
- SSLLogResumSess("===RESUMING SSL2 server-side session\n");
- if (ERR(err = SSL2InstallSessionKey(ctx)) != 0)
- return err;
- /* Fall through for matching session; lame, but true */
- case ssl2_mt_client_master_key:
- if (ERR(err = SSL2InitCiphers(ctx)) != 0)
- return err;
- if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerVerify, ctx)) != 0)
- return err;
- if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerFinished, ctx)) != 0)
- return err;
- SSLChangeHdskState(ctx, HandshakeSSL2ClientFinished);
- break;
- case ssl2_mt_server_hello:
- if (ctx->ssl2SessionMatch == 0)
- { if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientMasterKey, ctx)) != 0)
- return err;
- }
- else
- {
- SSLLogResumSess("===RESUMING SSL2 client-side session\n");
- if (ERR(err = SSL2InstallSessionKey(ctx)) != 0)
- return err;
- }
- if (ERR(err = SSL2InitCiphers(ctx)) != 0)
- return err;
- if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientFinished, ctx)) != 0)
- return err;
- SSLChangeHdskState(ctx, HandshakeSSL2ServerVerify);
- break;
- case ssl2_mt_client_finished:
- /* Handshake is complete; turn ciphers on */
- ctx->writeCipher.ready = 1;
- ctx->readCipher.ready = 1;
- /* original code never got out of ssl2_mt_client_finished state */
- CASSERT(ctx->protocolSide == SSL_ServerSide);
- SSLChangeHdskState(ctx, HandshakeServerReady);
- if (ctx->peerID.data != 0)
- ERR(SSLAddSessionData(ctx));
- break;
- case ssl2_mt_server_verify:
- SSLChangeHdskState(ctx, HandshakeSSL2ServerFinished);
- break;
- case ssl2_mt_request_certificate:
- if (ERR(err = SSL2SendError(ssl2_pe_no_certificate, ctx)) != 0)
- return err;
- break;
- case ssl2_mt_server_finished:
- /* Handshake is complete; turn ciphers on */
- ctx->writeCipher.ready = 1;
- ctx->readCipher.ready = 1;
- /* original code never got out of ssl2_mt_server_finished state */
- CASSERT(ctx->protocolSide == SSL_ClientSide);
- SSLChangeHdskState(ctx, HandshakeClientReady);
- if (ctx->peerID.data != 0)
- ERR(SSLAddSessionData(ctx));
- break;
- case ssl2_mt_error:
- case ssl2_mt_client_certificate:
- return ERR(SSLProtocolErr);
- break;
- }
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx)
-{ SSLErr err;
- SSLRecord rec;
-
- rec.contentType = SSL_version_2_0_record;
- rec.protocolVersion = SSL_Version_2_0;
- if (ERR(err = encodeFunc(&rec.contents, ctx)) != 0)
- return err;
-
- logSsl2Msg((SSL2MessageType)rec.contents.data[0], 1);
-
- assert(ctx->sslTslCalls != NULL);
- if (ERR(err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
- { ERR(SSLFreeBuffer(&rec.contents, &ctx->sysCtx));
- return err;
- }
-
- if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
- ctx->negProtocolVersion == SSL_Version_Undetermined)
- if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
- ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
- return err;
-
- ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx));
- return err;
-}
-
-SSLErr
-SSL2CompareSessionIDs(SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer sessionIdentifier;
-
- ctx->ssl2SessionMatch = 0;
-
- if (ctx->resumableSession.data == 0)
- return SSLNoErr;
-
- if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession,
- &sessionIdentifier, ctx)) != 0)
- return err;
-
- if (sessionIdentifier.length == ctx->sessionID.length &&
- memcmp(sessionIdentifier.data, ctx->sessionID.data, sessionIdentifier.length) == 0)
- ctx->ssl2SessionMatch = 1;
-
- if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
- return err;
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2InstallSessionKey(SSLContext *ctx)
-{ SSLErr err;
-
- CASSERT(ctx->ssl2SessionMatch != 0);
- CASSERT(ctx->resumableSession.data != 0);
- if (ERR(err = SSLInstallSessionFromData(ctx->resumableSession, ctx)) != 0)
- return err;
- return SSLNoErr;
-}
-
-SSLErr
-SSL2GenerateSessionID(SSLContext *ctx)
-{ SSLErr err;
-
- if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
- return err;
- if (ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx)) != 0)
- return err;
- if ((err = sslRand(ctx, &ctx->sessionID)) != 0)
- return err;
- return SSLNoErr;
-}
-
-SSLErr
-SSL2InitCiphers(SSLContext *ctx)
-{ SSLErr err;
- int keyMaterialLen;
- SSLBuffer keyData;
- uint8 variantChar, *progress, *readKey, *writeKey, *iv;
- SSLBuffer hashDigest, hashContext, masterKey, challenge, connectionID, variantData;
-
- keyMaterialLen = 2 * ctx->selectedCipherSpec->cipher->keySize;
- if (ERR(err = SSLAllocBuffer(&keyData, keyMaterialLen, &ctx->sysCtx)) != 0)
- return err;
-
- /* Can't have % in assertion string... */
- #if SSL_DEBUG
- {
- UInt32 keyModDigestSize = keyMaterialLen % SSLHashMD5.digestSize;
- CASSERT(keyModDigestSize == 0);
- }
- #endif
-
- masterKey.data = ctx->masterSecret;
- masterKey.length = ctx->selectedCipherSpec->cipher->keySize;
- challenge.data = ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
- ctx->ssl2ChallengeLength;
- challenge.length = ctx->ssl2ChallengeLength;
- connectionID.data = ctx->serverRandom;
- connectionID.length = ctx->ssl2ConnectionIDLength;
- variantData.data = &variantChar;
- variantData.length = 1;
- if (ERR(err = SSLAllocBuffer(&hashContext, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
- { ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
- return err;
- }
-
- variantChar = 0x30; /* '0' */
- progress = keyData.data;
- while (keyMaterialLen)
- { hashDigest.data = progress;
- hashDigest.length = SSLHashMD5.digestSize;
- if (ERR(err = SSLHashMD5.init(hashContext, ctx)) != 0 ||
- ERR(err = SSLHashMD5.update(hashContext, masterKey)) != 0 ||
- ERR(err = SSLHashMD5.update(hashContext, variantData)) != 0 ||
- ERR(err = SSLHashMD5.update(hashContext, challenge)) != 0 ||
- ERR(err = SSLHashMD5.update(hashContext, connectionID)) != 0 ||
- ERR(err = SSLHashMD5.final(hashContext, hashDigest)) != 0)
- { SSLFreeBuffer(&keyData, &ctx->sysCtx);
- SSLFreeBuffer(&hashContext, &ctx->sysCtx);
- return err;
- }
- progress += hashDigest.length;
- ++variantChar;
- keyMaterialLen -= hashDigest.length;
- }
-
- CASSERT(progress == keyData.data + keyData.length);
-
- if (ERR(err = SSLFreeBuffer(&hashContext, &ctx->sysCtx)) != 0)
- { ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
- return err;
- }
-
- ctx->readPending.macRef = ctx->selectedCipherSpec->macAlgorithm;
- ctx->writePending.macRef = ctx->selectedCipherSpec->macAlgorithm;
- ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
- ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
- ctx->readPending.sequenceNum = ctx->readCipher.sequenceNum;
- ctx->writePending.sequenceNum = ctx->writeCipher.sequenceNum;
-
- if (ctx->protocolSide == SSL_ServerSide)
- { writeKey = keyData.data;
- readKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
- }
- else
- { readKey = keyData.data;
- writeKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
- }
-
- iv = ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize;
-
- /* APPLE_CDSA symmetric cipher changes....*/
- if (ERR(err = ctx->readPending.symCipher->initialize(readKey, iv,
- &ctx->readPending, ctx)) != 0 ||
- ERR(err = ctx->writePending.symCipher->initialize(writeKey, iv,
- &ctx->writePending, ctx)) != 0)
- { ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
- return err;
- }
-
- /*
- * HEY! macSecret is only 20 bytes. This blows up when key size
- * is greater than 20, e.g., 3DES.
- * I'll increase the size of macSecret to 24, 'cause it appears
- * from the SSL v23 spec that the macSecret really the same size as
- * CLIENT-WRITE-KEY and SERVER-READ-KEY (see 1.2 of the spec).
- */
- memcpy(ctx->readPending.macSecret, readKey, ctx->selectedCipherSpec->cipher->keySize);
- memcpy(ctx->writePending.macSecret, writeKey, ctx->selectedCipherSpec->cipher->keySize);
-
- if (ERR(err = SSLFreeBuffer(&keyData, &ctx->sysCtx)) != 0)
- return err;
-
- ctx->readCipher = ctx->readPending;
- ctx->writeCipher = ctx->writePending;
- memset(&ctx->readPending, 0, sizeof(CipherContext)); /* Zero out old data */
- memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
-
- return SSLNoErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: ssl2rec.c
-
- Contains: Record encrypting/decrypting/MACing for SSL 2
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: ssl2rec.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ssl2rec.c Record encrypting/decrypting/MACing for SSL 2
-
-
- ****************************************************************** */
-
-#ifndef _SSL2_H_
-#include "ssl2.h"
-#endif
-
-#ifndef _SSLREC_H_
-#include "sslrec.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _DIGESTS_H_
-#include "digests.h"
-#endif
-
-#ifndef _APPLE_GLUE_H_
-#include "appleGlue.h"
-#endif
-
-#include <string.h>
-
-static SSLErr SSL2DecryptRecord(SSLBuffer *payload, SSLContext *ctx);
-static SSLErr SSL2VerifyMAC(SSLBuffer content, UInt8 *compareMAC, SSLContext *ctx);
-static SSLErr SSL2CalculateMAC(SSLBuffer secret, SSLBuffer content, UInt32 seqNo, const HashReference *hash, SSLBuffer mac, SSLContext *ctx);
-
-
-SSLErr
-SSL2ReadRecord(SSLRecord *rec, SSLContext *ctx)
-{ SSLErr err;
- UInt32 len, contentLen;
- int padding, headerSize;
- UInt8 *progress;
- SSLBuffer readData, cipherFragment;
-
- switch (ctx->negProtocolVersion)
- { case SSL_Version_Undetermined:
- case SSL_Version_3_0_With_2_0_Hello:
- case SSL_Version_2_0:
- break;
- case SSL_Version_3_0: /* We've negotiated a 3.0 session; we can send an alert */
- case TLS_Version_1_0:
- SSLFatalSessionAlert(alert_unexpected_message, ctx);
- return SSLProtocolErr;
- case SSL_Version_3_0_Only: /* We haven't yet negotiated, but we don't want to support 2.0; just die without an alert */
- return SSLProtocolErr;
- default:
- sslPanic("bad protocolVersion in ctx->protocolVersion");
- }
-
- if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < 3)
- { if (ctx->partialReadBuffer.data)
- if (ERR(err = SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return err;
- }
- if (ERR(err = SSLAllocBuffer(&ctx->partialReadBuffer, DEFAULT_BUFFER_SIZE, &ctx->sysCtx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return err;
- }
- }
-
- if (ctx->amountRead < 3)
- { readData.length = 3 - ctx->amountRead;
- readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
- len = readData.length;
- err = sslIoRead(readData, &len, ctx);
- if(err != 0)
- { if (err == SSLWouldBlockErr)
- ctx->amountRead += len;
- if (err == SSLIOErr && ctx->amountRead == 0) /* If the session closes on a record boundary, it's graceful */
- err = SSLConnectionClosedGraceful;
- return err;
- }
- ctx->amountRead += len;
- }
-
- rec->contentType = SSL_version_2_0_record;
- rec->protocolVersion = SSL_Version_2_0;
- progress = ctx->partialReadBuffer.data;
-
- if (((*progress) & 0x80) != 0) /* High bit on -> specifies 2-byte header */
- { headerSize = 2;
- contentLen = ((progress[0] & 0x7F) << 8) | progress[1];
- padding = 0;
- }
- else if (((*progress) & 0x40) != 0) /* Bit 6 on -> specifies security escape */
- { return ERR(SSLProtocolErr); /* No security escapes are defined */
- }
- else /* 3-byte header */
- { headerSize = 3;
- contentLen = ((progress[0] & 0x3F) << 8) | progress[1];
- padding = progress[2];
- }
-
- /*
- * FIXME - what's the max record size?
- * and why doesn't SSLReadRecord parse the 2 or 3 byte header?
- * Note: I see contentLen of 0 coming back from www.cduniverse.com when
- * it's only been given SSL_RSA_EXPORT_WITH_DES40_CBC_SHA.
- */
- if((contentLen == 0) || (contentLen > 0xffff)) {
- return SSLProtocolErr;
- }
-
- progress += headerSize;
-
- if (ctx->partialReadBuffer.length < headerSize + contentLen)
- { if (ERR(err = SSLReallocBuffer(&ctx->partialReadBuffer, 5 + contentLen, &ctx->sysCtx)) != 0)
- return err;
- }
-
- if (ctx->amountRead < headerSize + contentLen)
- { readData.length = headerSize + contentLen - ctx->amountRead;
- readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
- len = readData.length;
- err = sslIoRead(readData, &len, ctx);
- if(err != 0)
- { if (err == SSLWouldBlockErr)
- ctx->amountRead += len;
- return err;
- }
- ctx->amountRead += len;
- }
-
- cipherFragment.data = ctx->partialReadBuffer.data + headerSize;
- cipherFragment.length = contentLen;
- if (ERR(err = SSL2DecryptRecord(&cipherFragment, ctx)) != 0)
- return err;
-
- cipherFragment.length -= padding; /* Remove padding; MAC was removed by SSL2DecryptRecord */
-
- IncrementUInt64(&ctx->readCipher.sequenceNum);
-
-/* Allocate a buffer to return the plaintext in and return it */
- if (ERR(err = SSLAllocBuffer(&rec->contents, cipherFragment.length, &ctx->sysCtx)) != 0)
- return err;
- memcpy(rec->contents.data, cipherFragment.data, cipherFragment.length);
-
- ctx->amountRead = 0; /* We've used all the data in the cache */
-
- return SSLNoErr;
-}
-
-SSLErr
-SSL2WriteRecord(SSLRecord rec, SSLContext *ctx)
-{ SSLErr err;
- int padding = 0, i, headerSize;
- WaitingRecord *out, *queue;
- SSLBuffer buf, content, payload, secret, mac;
- UInt8 *progress;
- UInt16 payloadSize, blockSize;
-
- CASSERT(rec.contents.length < 16384);
-
- out = 0;
- /* Allocate a WaitingRecord to store our ready-to-send record in */
- if (ERR(err = SSLAllocBuffer(&buf, sizeof(WaitingRecord), &ctx->sysCtx)) != 0)
- return err;
- out = (WaitingRecord*)buf.data;
- out->next = 0;
- out->sent = 0;
-
- payloadSize = (UInt16)
- (rec.contents.length + ctx->writeCipher.macRef->hash->digestSize);
- blockSize = ctx->writeCipher.symCipher->blockSize;
- if (blockSize > 0)
- {
- padding = blockSize - (payloadSize % blockSize);
- if (padding == blockSize)
- padding = 0;
- payloadSize += padding;
- headerSize = 3;
- }
- else
- { padding = 0;
- headerSize = 2;
- }
- out->data.data = 0;
- if (ERR(err = SSLAllocBuffer(&out->data, headerSize + payloadSize, &ctx->sysCtx)) != 0)
- goto fail;
- progress = out->data.data;
-
- if (headerSize == 2)
- progress = SSLEncodeInt(progress, payloadSize | 0x8000, 2);
- else
- { progress = SSLEncodeInt(progress, payloadSize, 2);
- *progress++ = padding;
- }
-
- payload.data = progress;
- payload.length = payloadSize;
-
- mac.data = progress;
- mac.length = ctx->writeCipher.macRef->hash->digestSize;
- progress += mac.length;
-
- content.data = progress;
- content.length = rec.contents.length + padding;
- memcpy(progress, rec.contents.data, rec.contents.length);
- progress += rec.contents.length;
- i = padding;
- while (i--)
- *progress++ = padding;
-
- CASSERT(progress == out->data.data + out->data.length);
-
- secret.data = ctx->writeCipher.macSecret;
- secret.length = ctx->writeCipher.symCipher->keySize;
- if (mac.length > 0)
- if (ERR(err = SSL2CalculateMAC(secret, content,
- ctx->writeCipher.sequenceNum.low,
- ctx->writeCipher.macRef->hash, mac, ctx)) != 0)
- goto fail;
-
- /* APPLE_CDSA change...*/
- if (ERR(err = ctx->writeCipher.symCipher->encrypt(payload,
- payload,
- &ctx->writeCipher,
- ctx)) != 0)
- goto fail;
-
- /* Enqueue the record to be written from the idle loop */
- if (ctx->recordWriteQueue == 0)
- ctx->recordWriteQueue = out;
- else
- { queue = ctx->recordWriteQueue;
- while (queue->next != 0)
- queue = queue->next;
- queue->next = out;
- }
-
- /* Increment the sequence number */
- IncrementUInt64(&ctx->writeCipher.sequenceNum);
-
- return SSLNoErr;
-
-fail: /* Only for if we fail between when the WaitingRecord is allocated and when it is queued */
- SSLFreeBuffer(&out->data, 0);
- buf.data = (UInt8*)out;
- buf.length = sizeof(WaitingRecord);
- SSLFreeBuffer(&buf, &ctx->sysCtx);
- return err;
-}
-
-static SSLErr
-SSL2DecryptRecord(SSLBuffer *payload, SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer content;
-
- if (ctx->readCipher.symCipher->blockSize > 0)
- if (payload->length % ctx->readCipher.symCipher->blockSize != 0)
- return ERR(SSLProtocolErr);
-
-/* Decrypt in place */
- /* APPLE_CDSA change...*/
- if (ERR(err = ctx->readCipher.symCipher->decrypt(*payload,
- *payload,
- &ctx->readCipher,
- ctx)) != 0)
- return err;
-
- if (ctx->readCipher.macRef->hash->digestSize > 0) /* Optimize away MAC for null case */
- { content.data = payload->data + ctx->readCipher.macRef->hash->digestSize; /* Data is after MAC */
- content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
- if (ERR(err = SSL2VerifyMAC(content, payload->data, ctx)) != 0)
- return err;
- /* Adjust payload to remove MAC; caller is still responsible for removing padding [if any] */
- *payload = content;
- }
-
- return SSLNoErr;
-}
-
-#define IGNORE_MAC_FAILURE 0
-
-static SSLErr
-SSL2VerifyMAC(SSLBuffer content, UInt8 *compareMAC, SSLContext *ctx)
-{ SSLErr err;
- UInt8 calculatedMAC[MAX_DIGEST_SIZE];
- SSLBuffer secret, mac;
-
- secret.data = ctx->readCipher.macSecret;
- secret.length = ctx->readCipher.symCipher->keySize;
- mac.data = calculatedMAC;
- mac.length = ctx->readCipher.macRef->hash->digestSize;
- if (ERR(err = SSL2CalculateMAC(secret, content, ctx->readCipher.sequenceNum.low,
- ctx->readCipher.macRef->hash, mac, ctx)) != 0)
- return err;
- if (memcmp(mac.data, compareMAC, mac.length) != 0) {
- #if IGNORE_MAC_FAILURE
- dprintf0("SSL2VerifyMAC: Mac verify failure\n");
- return SSLNoErr;
- #else
- errorLog0("SSL2VerifyMAC: Mac verify failure\n");
- return ERR(SSLProtocolErr);
- #endif
- }
- return SSLNoErr;
-}
-
-#define LOG_MAC_DATA 0
-#if LOG_MAC_DATA
-static void logMacData(
- char *field,
- SSLBuffer *data)
-{
- int i;
-
- printf("%s: ", field);
- for(i=0; i<data->length; i++) {
- printf("%02X", data->data[i]);
- if((i % 4) == 3) {
- printf(" ");
- }
- }
- printf("\n");
-}
-#else /* LOG_MAC_DATA */
-#define logMacData(f, d)
-#endif /* LOG_MAC_DATA */
-
-/* For SSL 2, the MAC is hash ( secret || content || sequence# )
- * where secret is the decryption key for the message, content is
- * the record data plus any padding used to round out the record
- * size to an even multiple of the block size and sequence# is
- * a monotonically increasing 32-bit unsigned integer.
- */
-static SSLErr
-SSL2CalculateMAC(SSLBuffer secret, SSLBuffer content, UInt32 seqNo, const HashReference *hash, SSLBuffer mac, SSLContext *ctx)
-{ SSLErr err;
- UInt8 sequenceNum[4];
- SSLBuffer seqData, hashContext;
-
- SSLEncodeInt(sequenceNum, seqNo, 4);
- seqData.data = sequenceNum;
- seqData.length = 4;
-
- hashContext.data = 0;
- if (ERR(err = ReadyHash(hash, &hashContext, ctx)) != 0)
- return err;
- if (ERR(err = hash->update(hashContext, secret)) != 0)
- goto fail;
- if (ERR(err = hash->update(hashContext, content)) != 0)
- goto fail;
- if (ERR(err = hash->update(hashContext, seqData)) != 0)
- goto fail;
- if (ERR(err = hash->final(hashContext, mac)) != 0)
- goto fail;
-
- logMacData("secret ", &secret);
- logMacData("seqData", &seqData);
- logMacData("mac ", &mac);
-
- err = SSLNoErr;
-fail:
- ERR(SSLFreeBuffer(&hashContext, &ctx->sysCtx));
- return err;
-}
-
-SSLErr
-SSL2SendError(SSL2ErrorCode error, SSLContext *ctx)
-{ SSLErr err;
- SSLRecord rec;
- UInt8 errorData[3];
-
- rec.contentType = SSL_version_2_0_record;
- rec.protocolVersion = SSL_Version_2_0;
- rec.contents.data = errorData;
- rec.contents.length = 3;
- errorData[0] = ssl2_mt_error;
- SSLEncodeInt(errorData + 1, error, 2);
-
- ERR(err = SSL2WriteRecord(rec, ctx));
- return err;
-}
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: ssl3Callouts.c
-
- Contains: SSLv3-specific routines for SslTlsCallouts.
-
- Written by: Doug Mitchell
-*/
-
-#include "sslalloc.h"
-#include "tls_ssl.h"
-#include "sslutil.h"
-#include "digests.h"
-#include "ssl2.h"
-#include "sslDebug.h"
-#include "sslalert.h"
-#include <assert.h>
-#include <strings.h>
-
-/*
- * ssl3WriteRecord does not send alerts on failure, out of the assumption/fear
- * that this might result in a loop (since sending an alert causes ssl3WriteRecord
- * to be called).
- *
- * As far as I can tell, we can use this same routine for SSLv3 and TLSv1, as long
- * as we're not trying to use the "variable length padding" feature of TLSv1.
- * OpenSSL doesn't use that feature; for now, neither will we. Thus this routine
- * is used for the SslTlsCallouts.writeRecord function for both protocols.
- */
-SSLErr ssl3WriteRecord(
- SSLRecord rec,
- SSLContext *ctx)
-{
- SSLErr err;
- int padding = 0, i;
- WaitingRecord *out, *queue;
- SSLBuffer buf, payload, mac;
- UInt8 *progress;
- UInt16 payloadSize,blockSize;
-
- switch(rec.protocolVersion) {
- case SSL_Version_2_0:
- return SSL2WriteRecord(rec, ctx);
- case SSL_Version_3_0:
- case TLS_Version_1_0:
- break;
- default:
- assert(0);
- return SSLInternalError;
- }
- assert(rec.contents.length <= 16384);
-
- out = 0;
- /* Allocate a WaitingRecord to store our ready-to-send record in */
- if ((err = SSLAllocBuffer(&buf, sizeof(WaitingRecord), &ctx->sysCtx)) != 0)
- return err;
- out = (WaitingRecord*)buf.data;
- out->next = 0;
- out->sent = 0;
- /* Allocate enough room for the transmitted record, which will be:
- * 5 bytes of header +
- * encrypted contents +
- * macLength +
- * padding [block ciphers only] +
- * padding length field (1 byte) [block ciphers only]
- */
- payloadSize = (UInt16) (rec.contents.length + ctx->writeCipher.macRef->hash->digestSize);
- blockSize = ctx->writeCipher.symCipher->blockSize;
- if (blockSize > 0)
- { padding = blockSize - (payloadSize % blockSize) - 1;
- payloadSize += padding + 1;
- }
- out->data.data = 0;
- if ((err = SSLAllocBuffer(&out->data, 5 + payloadSize, &ctx->sysCtx)) != 0)
- goto fail;
-
- progress = out->data.data;
- *(progress++) = rec.contentType;
- progress = SSLEncodeInt(progress, rec.protocolVersion, 2);
- progress = SSLEncodeInt(progress, payloadSize, 2);
-
- /* Copy the contents into the output buffer */
- memcpy(progress, rec.contents.data, rec.contents.length);
- payload.data = progress;
- payload.length = rec.contents.length;
-
- progress += rec.contents.length;
- /* MAC immediately follows data */
- mac.data = progress;
- mac.length = ctx->writeCipher.macRef->hash->digestSize;
- progress += mac.length;
-
- /* MAC the data */
- if (mac.length > 0) /* Optimize away null case */
- {
- assert(ctx->sslTslCalls != NULL);
- if ((err = ctx->sslTslCalls->computeMac(rec.contentType,
- payload,
- mac,
- &ctx->writeCipher,
- ctx->writeCipher.sequenceNum,
- ctx)) != 0)
- goto fail;
- }
-
- /* Update payload to reflect encrypted data: contents, mac & padding */
- payload.length = payloadSize;
-
- /* Fill in the padding bytes & padding length field with the padding value; the
- * protocol only requires the last byte,
- * but filling them all in avoids leaking data
- */
- if (ctx->writeCipher.symCipher->blockSize > 0)
- for (i = 1; i <= padding + 1; ++i)
- payload.data[payload.length - i] = padding;
-
- /* Encrypt the data */
- if ((err = ctx->writeCipher.symCipher->encrypt(payload,
- payload,
- &ctx->writeCipher,
- ctx)) != 0)
- goto fail;
- DUMP_BUFFER_NAME("encrypted data", payload);
-
- /* Enqueue the record to be written from the idle loop */
- if (ctx->recordWriteQueue == 0)
- ctx->recordWriteQueue = out;
- else
- { queue = ctx->recordWriteQueue;
- while (queue->next != 0)
- queue = queue->next;
- queue->next = out;
- }
-
- /* Increment the sequence number */
- IncrementUInt64(&ctx->writeCipher.sequenceNum);
-
- return SSLNoErr;
-
-fail:
- /*
- * Only for if we fail between when the WaitingRecord is allocated and when
- * it is queued
- */
- SSLFreeBuffer(&out->data, &ctx->sysCtx);
- buf.data = (UInt8*)out;
- buf.length = sizeof(WaitingRecord);
- SSLFreeBuffer(&buf, &ctx->sysCtx);
- return ERR(err);
-}
-
-static SSLErr ssl3DecryptRecord(
- UInt8 type,
- SSLBuffer *payload,
- SSLContext *ctx)
-{
- SSLErr err;
- SSLBuffer content;
-
- if ((ctx->readCipher.symCipher->blockSize > 0) &&
- ((payload->length % ctx->readCipher.symCipher->blockSize) != 0))
- { SSLFatalSessionAlert(alert_unexpected_message, ctx);
- return ERR(SSLProtocolErr);
- }
-
- /* Decrypt in place */
- DUMP_BUFFER_NAME("encrypted data", (*payload));
- if ((err = ctx->readCipher.symCipher->decrypt(*payload,
- *payload,
- &ctx->readCipher,
- ctx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return ERR(err);
- }
- DUMP_BUFFER_NAME("decrypted data", (*payload));
-
- /* Locate content within decrypted payload */
- content.data = payload->data;
- content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
- if (ctx->readCipher.symCipher->blockSize > 0)
- { /* padding can't be equal to or more than a block */
- if (payload->data[payload->length - 1] >= ctx->readCipher.symCipher->blockSize)
- { SSLFatalSessionAlert(alert_unexpected_message, ctx);
- errorLog1("DecryptSSLRecord: bad padding length (%d)\n",
- (unsigned)payload->data[payload->length - 1]);
- return ERR(SSLProtocolErr);
- }
- content.length -= 1 + payload->data[payload->length - 1];
- /* Remove block size padding */
- }
-
- /* Verify MAC on payload */
- if (ctx->readCipher.macRef->hash->digestSize > 0)
- /* Optimize away MAC for null case */
- if ((err = SSLVerifyMac(type, content,
- payload->data + content.length, ctx)) != 0)
- { SSLFatalSessionAlert(alert_bad_record_mac, ctx);
- return ERR(err);
- }
-
- *payload = content; /* Modify payload buffer to indicate content length */
-
- return SSLNoErr;
-}
-
-/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
-static SSLErr ssl3InitMac (
- CipherContext *cipherCtx, // macRef, macSecret valid on entry
- // macCtx valid on return
- SSLContext *ctx)
-{
- const HashReference *hash;
- SSLBuffer *hashCtx;
- SSLErr serr;
-
- assert(cipherCtx->macRef != NULL);
- hash = cipherCtx->macRef->hash;
- assert(hash != NULL);
-
- hashCtx = &cipherCtx->macCtx.hashCtx;
- if(hashCtx->data != NULL) {
- SSLFreeBuffer(hashCtx, &ctx->sysCtx);
- }
- serr = SSLAllocBuffer(hashCtx, hash->contextSize, &ctx->sysCtx);
- if(serr) {
- return serr;
- }
- return SSLNoErr;
-}
-
-static SSLErr ssl3FreeMac (
- CipherContext *cipherCtx)
-{
- SSLBuffer *hashCtx;
-
- assert(cipherCtx != NULL);
- /* this can be called on a completely zeroed out CipherContext... */
- if(cipherCtx->macRef == NULL) {
- return SSLNoErr;
- }
- hashCtx = &cipherCtx->macCtx.hashCtx;
- if(hashCtx->data != NULL) {
- sslFree(hashCtx->data);
- hashCtx->data = NULL;
- }
- hashCtx->length = 0;
- return SSLNoErr;
-}
-
-static SSLErr ssl3ComputeMac (
- UInt8 type,
- SSLBuffer data,
- SSLBuffer mac, // caller mallocs data
- CipherContext *cipherCtx, // assumes macCtx, macRef
- sslUint64 seqNo,
- SSLContext *ctx)
-{
- SSLErr err;
- UInt8 innerDigestData[MAX_DIGEST_SIZE];
- UInt8 scratchData[11], *progress;
- SSLBuffer digest, digestCtx, scratch;
- SSLBuffer secret;
-
- const HashReference *hash;
-
- assert(cipherCtx != NULL);
- assert(cipherCtx->macRef != NULL);
- hash = cipherCtx->macRef->hash;
- assert(hash != NULL);
- assert(hash->macPadSize <= MAX_MAC_PADDING);
- assert(hash->digestSize <= MAX_DIGEST_SIZE);
- digestCtx = cipherCtx->macCtx.hashCtx; // may be NULL, for null cipher
- secret.data = cipherCtx->macSecret;
- secret.length = hash->digestSize;
-
- /* init'd early in SSLNewContext() */
- assert(SSLMACPad1[0] == 0x36 && SSLMACPad2[0] == 0x5C);
-
- /*
- * MAC = hash( MAC_write_secret + pad_2 +
- * hash( MAC_write_secret + pad_1 + seq_num + type +
- * length + content )
- * )
- */
- if ((err = hash->init(digestCtx, ctx)) != 0)
- goto exit;
- if ((err = hash->update(digestCtx, secret)) != 0) /* MAC secret */
- goto exit;
- scratch.data = SSLMACPad1;
- scratch.length = hash->macPadSize;
- if ((err = hash->update(digestCtx, scratch)) != 0) /* pad1 */
- goto exit;
- progress = scratchData;
- progress = SSLEncodeUInt64(progress, seqNo);
- *progress++ = type;
- progress = SSLEncodeInt(progress, data.length, 2);
- scratch.data = scratchData;
- scratch.length = 11;
- assert(progress = scratchData+11);
- if ((err = hash->update(digestCtx, scratch)) != 0)
- /* sequenceNo, type & length */
- goto exit;
- if ((err = hash->update(digestCtx, data)) != 0) /* content */
- goto exit;
- digest.data = innerDigestData;
- digest.length = hash->digestSize;
- if ((err = hash->final(digestCtx, digest)) != 0) /* figure inner digest */
- goto exit;
-
- if ((err = hash->init(digestCtx, ctx)) != 0)
- goto exit;
- if ((err = hash->update(digestCtx, secret)) != 0) /* MAC secret */
- goto exit;
- scratch.data = SSLMACPad2;
- scratch.length = hash->macPadSize;
- if ((err = hash->update(digestCtx, scratch)) != 0) /* pad2 */
- goto exit;
- if ((err = hash->update(digestCtx, digest)) != 0) /* inner digest */
- goto exit;
- if ((err = hash->final(digestCtx, mac)) != 0) /* figure the mac */
- goto exit;
-
- err = SSLNoErr; /* redundant, I know */
-
-exit:
- return err;
-}
-
-#define LOG_GEN_KEY 0
-
-/*
- * On input, the following are valid:
- * MasterSecret[48]
- * ClientHello.random[32]
- * ServerHello.random[32]
- *
- * key_block =
- * MD5(master_secret + SHA(`A' + master_secret +
- * ServerHello.random +
- * ClientHello.random)) +
- * MD5(master_secret + SHA(`BB' + master_secret +
- * ServerHello.random +
- * ClientHello.random)) +
- * MD5(master_secret + SHA(`CCC' + master_secret +
- * ServerHello.random +
- * ClientHello.random)) + [...];
- */
-static SSLErr ssl3GenerateKeyMaterial (
- SSLBuffer key, // caller mallocs and specifies length of
- // required key material here
- SSLContext *ctx)
-{
- SSLErr err;
- UInt8 leaderData[10]; /* Max of 10 hashes
- * (* 16 bytes/hash = 160 bytes of key) */
- UInt8 shaHashData[20], md5HashData[16];
- SSLBuffer shaContext, md5Context;
- UInt8 *keyProgress;
- int i,j,remaining, satisfied;
- SSLBuffer leader, masterSecret, serverRandom, clientRandom, shaHash, md5Hash;
-
- #if LOG_GEN_KEY
- printf("GenerateKey: master ");
- for(i=0; i<SSL_MASTER_SECRET_SIZE; i++) {
- printf("%02X ", ctx->masterSecret[i]);
- }
- printf("\n");
- #endif
-
- assert(key.length <= 16 * sizeof(leaderData));
-
- leader.data = leaderData;
- masterSecret.data = ctx->masterSecret;
- masterSecret.length = SSL_MASTER_SECRET_SIZE;
- serverRandom.data = ctx->serverRandom;
- serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- clientRandom.data = ctx->clientRandom;
- clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- shaHash.data = shaHashData;
- shaHash.length = 20;
- md5Hash.data = md5HashData;
- md5Hash.length = 16;
-
- md5Context.data = 0;
- shaContext.data = 0;
- if ((err = ReadyHash(&SSLHashMD5, &md5Context, ctx)) != 0)
- goto fail;
- if ((err = ReadyHash(&SSLHashSHA1, &shaContext, ctx)) != 0)
- goto fail;
-
- keyProgress = key.data;
- remaining = key.length;
-
- for (i = 0; remaining > 0; ++i)
- { for (j = 0; j <= i; j++)
- leaderData[j] = 0x41 + i; /* 'A', 'BB', 'CCC', etc. */
- leader.length = i+1;
-
- if ((err = SSLHashSHA1.update(shaContext, leader)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.update(shaContext, masterSecret)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.update(shaContext, serverRandom)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.update(shaContext, clientRandom)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.final(shaContext, shaHash)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(md5Context, masterSecret)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(md5Context, shaHash)) != 0)
- goto fail;
- if ((err = SSLHashMD5.final(md5Context, md5Hash)) != 0)
- goto fail;
-
- satisfied = 16;
- if (remaining < 16)
- satisfied = remaining;
- memcpy(keyProgress, md5HashData, satisfied);
- remaining -= satisfied;
- keyProgress += satisfied;
-
- if(remaining > 0) {
- /* at top of loop, this was done in ReadyHash() */
- if ((err = SSLHashMD5.init(md5Context, ctx)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.init(shaContext, ctx)) != 0)
- goto fail;
- }
- }
-
- assert(remaining == 0 && keyProgress == (key.data + key.length));
- err = SSLNoErr;
-fail:
- SSLFreeBuffer(&md5Context, &ctx->sysCtx);
- SSLFreeBuffer(&shaContext, &ctx->sysCtx);
-
- #if LOG_GEN_KEY
- printf("GenerateKey: DONE\n");
- #endif
- return err;
-}
-
-static SSLErr ssl3GenerateExportKeyAndIv (
- SSLContext *ctx, // clientRandom, serverRandom valid
- const SSLBuffer clientWriteKey,
- const SSLBuffer serverWriteKey,
- SSLBuffer finalClientWriteKey, // RETURNED, mallocd by caller
- SSLBuffer finalServerWriteKey, // RETURNED, mallocd by caller
- SSLBuffer finalClientIV, // RETURNED, mallocd by caller
- SSLBuffer finalServerIV) // RETURNED, mallocd by caller
-{
- SSLErr err;
- SSLBuffer hashCtx, serverRandom, clientRandom;
-
- /* random blobs are 32 bytes */
- serverRandom.data = ctx->serverRandom;
- serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- clientRandom.data = ctx->clientRandom;
- clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
-
- if ((err = SSLAllocBuffer(&hashCtx, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
- return err;
- /* client write key */
- if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, clientWriteKey)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
- goto fail;
- finalClientWriteKey.length = 16;
- if ((err = SSLHashMD5.final(hashCtx, finalClientWriteKey)) != 0)
- goto fail;
-
- /* optional client IV */
- if (ctx->selectedCipherSpec->cipher->ivSize > 0)
- { if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
- goto fail;
- finalClientIV.length = 16;
- if ((err = SSLHashMD5.final(hashCtx, finalClientIV)) != 0)
- goto fail;
- }
-
- /* server write key */
- if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, serverWriteKey)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
- goto fail;
- finalServerWriteKey.length = 16;
- if ((err = SSLHashMD5.final(hashCtx, finalServerWriteKey)) != 0)
- goto fail;
-
- /* optional server IV */
- if (ctx->selectedCipherSpec->cipher->ivSize > 0)
- { if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
- goto fail;
- finalServerIV.length = 16;
- if ((err = SSLHashMD5.final(hashCtx, finalServerIV)) != 0)
- goto fail;
- }
-
- err = SSLNoErr;
-fail:
- SSLFreeBuffer(&hashCtx, &ctx->sysCtx);
- return err;
-}
-
-/*
- * On entry: clientRandom, serverRandom, preMasterSecret valid
- * On return: masterSecret valid
- */
-static SSLErr ssl3GenerateMasterSecret (
- SSLContext *ctx)
-{
- SSLErr err;
- SSLBuffer shaState, md5State, clientRandom,
- serverRandom, shaHash, md5Hash, leader;
- UInt8 *masterProgress, shaHashData[20], leaderData[3];
- int i;
-
- md5State.data = shaState.data = 0;
- if ((err = SSLAllocBuffer(&md5State, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
- goto fail;
- if ((err = SSLAllocBuffer(&shaState, SSLHashSHA1.contextSize, &ctx->sysCtx)) != 0)
- goto fail;
-
- clientRandom.data = ctx->clientRandom;
- clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- serverRandom.data = ctx->serverRandom;
- serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
- shaHash.data = shaHashData;
- shaHash.length = 20;
-
- masterProgress = ctx->masterSecret;
-
- for (i = 1; i <= 3; i++)
- { if ((err = SSLHashMD5.init(md5State, ctx)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.init(shaState, ctx)) != 0)
- goto fail;
-
- leaderData[0] = leaderData[1] = leaderData[2] = 0x40 + i; /* 'A', 'B', etc. */
- leader.data = leaderData;
- leader.length = i;
-
- if ((err = SSLHashSHA1.update(shaState, leader)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.update(shaState, ctx->preMasterSecret)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.update(shaState, clientRandom)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.update(shaState, serverRandom)) != 0)
- goto fail;
- if ((err = SSLHashSHA1.final(shaState, shaHash)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(md5State, ctx->preMasterSecret)) != 0)
- goto fail;
- if ((err = SSLHashMD5.update(md5State, shaHash)) != 0)
- goto fail;
- md5Hash.data = masterProgress;
- md5Hash.length = 16;
- if ((err = SSLHashMD5.final(md5State, md5Hash)) != 0)
- goto fail;
- masterProgress += 16;
- }
-
- err = SSLNoErr;
-fail:
- SSLFreeBuffer(&shaState, &ctx->sysCtx);
- SSLFreeBuffer(&md5State, &ctx->sysCtx);
- return err;
-}
-
-/* common routine to compute a Mac for finished message and cert verify message */
-static SSLErr
-ssl3CalculateFinishedMessage(
- SSLContext *ctx,
- SSLBuffer finished, // mallocd by caller
- SSLBuffer shaMsgState, // running total
- SSLBuffer md5MsgState, // ditto
- UInt32 senderID) // optional, nonzero for finished message
-{
- SSLErr err;
- SSLBuffer hash, input;
- UInt8 sender[4], md5Inner[16], shaInner[20];
-
- // assert(finished.length == 36);
-
- if (senderID != 0) {
- SSLEncodeInt(sender, senderID, 4);
- input.data = sender;
- input.length = 4;
- if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
- return err;
- if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
- return err;
- }
- input.data = ctx->masterSecret;
- input.length = SSL_MASTER_SECRET_SIZE;
- if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
- return err;
- if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
- return err;
- input.data = SSLMACPad1;
- input.length = SSLHashMD5.macPadSize;
- if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
- return err;
- input.length = SSLHashSHA1.macPadSize;
- if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
- return err;
- hash.data = md5Inner;
- hash.length = 16;
- if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
- return err;
- hash.data = shaInner;
- hash.length = 20;
- if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
- return err;
- if ((err = SSLHashMD5.init(md5MsgState, ctx)) != 0)
- return err;
- if ((err = SSLHashSHA1.init(shaMsgState, ctx)) != 0)
- return err;
- input.data = ctx->masterSecret;
- input.length = SSL_MASTER_SECRET_SIZE;
- if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
- return err;
- if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
- return err;
- input.data = SSLMACPad2;
- input.length = SSLHashMD5.macPadSize;
- if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
- return err;
- input.length = SSLHashSHA1.macPadSize;
- if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
- return err;
- input.data = md5Inner;
- input.length = 16;
- if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
- return err;
- hash.data = finished.data;
- hash.length = 16;
- if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
- return err;
- input.data = shaInner;
- input.length = 20;
- if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
- return err;
- hash.data = finished.data + 16;
- hash.length = 20;
- if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
- return err;
- return SSLNoErr;
-}
-
-
-static SSLErr ssl3ComputeFinishedMac (
- SSLContext *ctx,
- SSLBuffer finished, // output - mallocd by caller
- SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
- SSLBuffer md5MsgState, // ditto
- Boolean isServer) // refers to message, not us
-{
- return ssl3CalculateFinishedMessage(ctx, finished, shaMsgState, md5MsgState,
- isServer ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client);
-}
-
-static SSLErr ssl3ComputeCertVfyMac (
- SSLContext *ctx,
- SSLBuffer finished, // output - mallocd by caller
- SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
- SSLBuffer md5MsgState) // ditto
-{
- return ssl3CalculateFinishedMessage(ctx, finished, shaMsgState, md5MsgState, 0);
-}
-
-const SslTlsCallouts Ssl3Callouts = {
- ssl3DecryptRecord,
- ssl3WriteRecord,
- ssl3InitMac,
- ssl3FreeMac,
- ssl3ComputeMac,
- ssl3GenerateKeyMaterial,
- ssl3GenerateExportKeyAndIv,
- ssl3GenerateMasterSecret,
- ssl3ComputeFinishedMac,
- ssl3ComputeCertVfyMac
-};
--- /dev/null
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: ssl3Callouts.cpp
+
+ Contains: SSLv3-specific routines for SslTlsCallouts.
+
+ Written by: Doug Mitchell
+*/
+
+#include "sslMemory.h"
+#include "tls_ssl.h"
+#include "sslUtils.h"
+#include "sslDigests.h"
+#include "ssl2.h"
+#include "sslDebug.h"
+#include "sslAlertMessage.h"
+
+#include <assert.h>
+#include <strings.h>
+
+/*
+ * ssl3WriteRecord does not send alerts on failure, out of the assumption/fear
+ * that this might result in a loop (since sending an alert causes ssl3WriteRecord
+ * to be called).
+ *
+ * As far as I can tell, we can use this same routine for SSLv3 and TLSv1, as long
+ * as we're not trying to use the "variable length padding" feature of TLSv1.
+ * OpenSSL doesn't use that feature; for now, neither will we. Thus this routine
+ * is used for the SslTlsCallouts.writeRecord function for both protocols.
+ */
+OSStatus ssl3WriteRecord(
+ SSLRecord rec,
+ SSLContext *ctx)
+{
+ OSStatus err;
+ int padding = 0, i;
+ WaitingRecord *out, *queue;
+ SSLBuffer buf, payload, mac;
+ UInt8 *charPtr;
+ UInt16 payloadSize,blockSize;
+
+ switch(rec.protocolVersion) {
+ case SSL_Version_2_0:
+ return SSL2WriteRecord(rec, ctx);
+ case SSL_Version_3_0:
+ case TLS_Version_1_0:
+ break;
+ default:
+ assert(0);
+ return errSSLInternal;
+ }
+ assert(rec.contents.length <= 16384);
+
+ out = 0;
+ /* Allocate a WaitingRecord to store our ready-to-send record in */
+ if ((err = SSLAllocBuffer(buf, sizeof(WaitingRecord), ctx)) != 0)
+ return err;
+ out = (WaitingRecord*)buf.data;
+ out->next = 0;
+ out->sent = 0;
+ /* Allocate enough room for the transmitted record, which will be:
+ * 5 bytes of header +
+ * encrypted contents +
+ * macLength +
+ * padding [block ciphers only] +
+ * padding length field (1 byte) [block ciphers only]
+ */
+ payloadSize = (UInt16) (rec.contents.length + ctx->writeCipher.macRef->hash->digestSize);
+ blockSize = ctx->writeCipher.symCipher->blockSize;
+ if (blockSize > 0)
+ { padding = blockSize - (payloadSize % blockSize) - 1;
+ payloadSize += padding + 1;
+ }
+ out->data.data = 0;
+ if ((err = SSLAllocBuffer(out->data, 5 + payloadSize, ctx)) != 0)
+ goto fail;
+
+ charPtr = out->data.data;
+ *(charPtr++) = rec.contentType;
+ charPtr = SSLEncodeInt(charPtr, rec.protocolVersion, 2);
+ charPtr = SSLEncodeInt(charPtr, payloadSize, 2);
+
+ /* Copy the contents into the output buffer */
+ memcpy(charPtr, rec.contents.data, rec.contents.length);
+ payload.data = charPtr;
+ payload.length = rec.contents.length;
+
+ charPtr += rec.contents.length;
+ /* MAC immediately follows data */
+ mac.data = charPtr;
+ mac.length = ctx->writeCipher.macRef->hash->digestSize;
+ charPtr += mac.length;
+
+ /* MAC the data */
+ if (mac.length > 0) /* Optimize away null case */
+ {
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->computeMac(rec.contentType,
+ payload,
+ mac,
+ &ctx->writeCipher,
+ ctx->writeCipher.sequenceNum,
+ ctx)) != 0)
+ goto fail;
+ }
+
+ /* Update payload to reflect encrypted data: contents, mac & padding */
+ payload.length = payloadSize;
+
+ /* Fill in the padding bytes & padding length field with the padding value; the
+ * protocol only requires the last byte,
+ * but filling them all in avoids leaking data
+ */
+ if (ctx->writeCipher.symCipher->blockSize > 0)
+ for (i = 1; i <= padding + 1; ++i)
+ payload.data[payload.length - i] = padding;
+
+ /* Encrypt the data */
+ if ((err = ctx->writeCipher.symCipher->encrypt(payload,
+ payload,
+ &ctx->writeCipher,
+ ctx)) != 0)
+ goto fail;
+
+ /* Enqueue the record to be written from the idle loop */
+ if (ctx->recordWriteQueue == 0)
+ ctx->recordWriteQueue = out;
+ else
+ { queue = ctx->recordWriteQueue;
+ while (queue->next != 0)
+ queue = queue->next;
+ queue->next = out;
+ }
+
+ /* Increment the sequence number */
+ IncrementUInt64(&ctx->writeCipher.sequenceNum);
+
+ return noErr;
+
+fail:
+ /*
+ * Only for if we fail between when the WaitingRecord is allocated and when
+ * it is queued
+ */
+ SSLFreeBuffer(out->data, ctx);
+ buf.data = (UInt8*)out;
+ buf.length = sizeof(WaitingRecord);
+ SSLFreeBuffer(buf, ctx);
+ return err;
+}
+
+static OSStatus ssl3DecryptRecord(
+ UInt8 type,
+ SSLBuffer *payload,
+ SSLContext *ctx)
+{
+ OSStatus err;
+ SSLBuffer content;
+
+ if ((ctx->readCipher.symCipher->blockSize > 0) &&
+ ((payload->length % ctx->readCipher.symCipher->blockSize) != 0))
+ { SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ return errSSLProtocol;
+ }
+
+ /* Decrypt in place */
+ if ((err = ctx->readCipher.symCipher->decrypt(*payload,
+ *payload,
+ &ctx->readCipher,
+ ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+
+ /* Locate content within decrypted payload */
+ content.data = payload->data;
+ content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
+ if (ctx->readCipher.symCipher->blockSize > 0)
+ { /* padding can't be equal to or more than a block */
+ if (payload->data[payload->length - 1] >= ctx->readCipher.symCipher->blockSize)
+ { SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ sslErrorLog("DecryptSSLRecord: bad padding length (%d)\n",
+ (unsigned)payload->data[payload->length - 1]);
+ return errSSLProtocol;
+ }
+ content.length -= 1 + payload->data[payload->length - 1];
+ /* Remove block size padding */
+ }
+
+ /* Verify MAC on payload */
+ if (ctx->readCipher.macRef->hash->digestSize > 0)
+ /* Optimize away MAC for null case */
+ if ((err = SSLVerifyMac(type, content,
+ payload->data + content.length, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
+ return err;
+ }
+
+ *payload = content; /* Modify payload buffer to indicate content length */
+
+ return noErr;
+}
+
+/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
+static OSStatus ssl3InitMac (
+ CipherContext *cipherCtx, // macRef, macSecret valid on entry
+ // macCtx valid on return
+ SSLContext *ctx)
+{
+ const HashReference *hash;
+ SSLBuffer *hashCtx;
+ OSStatus serr;
+
+ assert(cipherCtx->macRef != NULL);
+ hash = cipherCtx->macRef->hash;
+ assert(hash != NULL);
+
+ hashCtx = &cipherCtx->macCtx.hashCtx;
+ if(hashCtx->data != NULL) {
+ SSLFreeBuffer(*hashCtx, ctx);
+ }
+ serr = SSLAllocBuffer(*hashCtx, hash->contextSize, ctx);
+ if(serr) {
+ return serr;
+ }
+ return noErr;
+}
+
+static OSStatus ssl3FreeMac (
+ CipherContext *cipherCtx)
+{
+ SSLBuffer *hashCtx;
+
+ assert(cipherCtx != NULL);
+ /* this can be called on a completely zeroed out CipherContext... */
+ if(cipherCtx->macRef == NULL) {
+ return noErr;
+ }
+ hashCtx = &cipherCtx->macCtx.hashCtx;
+ if(hashCtx->data != NULL) {
+ sslFree(hashCtx->data);
+ hashCtx->data = NULL;
+ }
+ hashCtx->length = 0;
+ return noErr;
+}
+
+static OSStatus ssl3ComputeMac (
+ UInt8 type,
+ SSLBuffer data,
+ SSLBuffer mac, // caller mallocs data
+ CipherContext *cipherCtx, // assumes macCtx, macRef
+ sslUint64 seqNo,
+ SSLContext *ctx)
+{
+ OSStatus err;
+ UInt8 innerDigestData[SSL_MAX_DIGEST_LEN];
+ UInt8 scratchData[11], *charPtr;
+ SSLBuffer digest, digestCtx, scratch;
+ SSLBuffer secret;
+
+ const HashReference *hash;
+
+ assert(cipherCtx != NULL);
+ assert(cipherCtx->macRef != NULL);
+ hash = cipherCtx->macRef->hash;
+ assert(hash != NULL);
+ assert(hash->macPadSize <= MAX_MAC_PADDING);
+ assert(hash->digestSize <= SSL_MAX_DIGEST_LEN);
+ digestCtx = cipherCtx->macCtx.hashCtx; // may be NULL, for null cipher
+ secret.data = cipherCtx->macSecret;
+ secret.length = hash->digestSize;
+
+ /* init'd early in SSLNewContext() */
+ assert(SSLMACPad1[0] == 0x36 && SSLMACPad2[0] == 0x5C);
+
+ /*
+ * MAC = hash( MAC_write_secret + pad_2 +
+ * hash( MAC_write_secret + pad_1 + seq_num + type +
+ * length + content )
+ * )
+ */
+ if ((err = hash->init(digestCtx, ctx)) != 0)
+ goto exit;
+ if ((err = hash->update(digestCtx, secret)) != 0) /* MAC secret */
+ goto exit;
+ scratch.data = (UInt8 *)SSLMACPad1;
+ scratch.length = hash->macPadSize;
+ if ((err = hash->update(digestCtx, scratch)) != 0) /* pad1 */
+ goto exit;
+ charPtr = scratchData;
+ charPtr = SSLEncodeUInt64(charPtr, seqNo);
+ *charPtr++ = type;
+ charPtr = SSLEncodeInt(charPtr, data.length, 2);
+ scratch.data = scratchData;
+ scratch.length = 11;
+ assert(charPtr = scratchData+11);
+ if ((err = hash->update(digestCtx, scratch)) != 0)
+ /* sequenceNo, type & length */
+ goto exit;
+ if ((err = hash->update(digestCtx, data)) != 0) /* content */
+ goto exit;
+ digest.data = innerDigestData;
+ digest.length = hash->digestSize;
+ if ((err = hash->final(digestCtx, digest)) != 0) /* figure inner digest */
+ goto exit;
+
+ if ((err = hash->init(digestCtx, ctx)) != 0)
+ goto exit;
+ if ((err = hash->update(digestCtx, secret)) != 0) /* MAC secret */
+ goto exit;
+ scratch.data = (UInt8 *)SSLMACPad2;
+ scratch.length = hash->macPadSize;
+ if ((err = hash->update(digestCtx, scratch)) != 0) /* pad2 */
+ goto exit;
+ if ((err = hash->update(digestCtx, digest)) != 0) /* inner digest */
+ goto exit;
+ if ((err = hash->final(digestCtx, mac)) != 0) /* figure the mac */
+ goto exit;
+
+ err = noErr; /* redundant, I know */
+
+exit:
+ return err;
+}
+
+#define LOG_GEN_KEY 0
+
+/*
+ * On input, the following are valid:
+ * MasterSecret[48]
+ * ClientHello.random[32]
+ * ServerHello.random[32]
+ *
+ * key_block =
+ * MD5(master_secret + SHA(`A' + master_secret +
+ * ServerHello.random +
+ * ClientHello.random)) +
+ * MD5(master_secret + SHA(`BB' + master_secret +
+ * ServerHello.random +
+ * ClientHello.random)) +
+ * MD5(master_secret + SHA(`CCC' + master_secret +
+ * ServerHello.random +
+ * ClientHello.random)) + [...];
+ */
+static OSStatus ssl3GenerateKeyMaterial (
+ SSLBuffer key, // caller mallocs and specifies length of
+ // required key material here
+ SSLContext *ctx)
+{
+ OSStatus err;
+ UInt8 leaderData[10]; /* Max of 10 hashes
+ * (* 16 bytes/hash = 160 bytes of key) */
+ UInt8 shaHashData[20], md5HashData[16];
+ SSLBuffer shaContext, md5Context;
+ UInt8 *keyProgress;
+ int i,j,remaining, satisfied;
+ SSLBuffer leader, masterSecret, serverRandom, clientRandom, shaHash, md5Hash;
+
+ #if LOG_GEN_KEY
+ printf("GenerateKey: master ");
+ for(i=0; i<SSL_MASTER_SECRET_SIZE; i++) {
+ printf("%02X ", ctx->masterSecret[i]);
+ }
+ printf("\n");
+ #endif
+
+ assert(key.length <= 16 * sizeof(leaderData));
+
+ leader.data = leaderData;
+ masterSecret.data = ctx->masterSecret;
+ masterSecret.length = SSL_MASTER_SECRET_SIZE;
+ serverRandom.data = ctx->serverRandom;
+ serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ clientRandom.data = ctx->clientRandom;
+ clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ shaHash.data = shaHashData;
+ shaHash.length = 20;
+ md5Hash.data = md5HashData;
+ md5Hash.length = 16;
+
+ md5Context.data = 0;
+ shaContext.data = 0;
+ if ((err = ReadyHash(SSLHashMD5, md5Context, ctx)) != 0)
+ goto fail;
+ if ((err = ReadyHash(SSLHashSHA1, shaContext, ctx)) != 0)
+ goto fail;
+
+ keyProgress = key.data;
+ remaining = key.length;
+
+ for (i = 0; remaining > 0; ++i)
+ { for (j = 0; j <= i; j++)
+ leaderData[j] = 0x41 + i; /* 'A', 'BB', 'CCC', etc. */
+ leader.length = i+1;
+
+ if ((err = SSLHashSHA1.update(shaContext, leader)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(shaContext, masterSecret)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(shaContext, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(shaContext, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.final(shaContext, shaHash)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(md5Context, masterSecret)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(md5Context, shaHash)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.final(md5Context, md5Hash)) != 0)
+ goto fail;
+
+ satisfied = 16;
+ if (remaining < 16)
+ satisfied = remaining;
+ memcpy(keyProgress, md5HashData, satisfied);
+ remaining -= satisfied;
+ keyProgress += satisfied;
+
+ if(remaining > 0) {
+ /* at top of loop, this was done in ReadyHash() */
+ if ((err = SSLHashMD5.init(md5Context, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.init(shaContext, ctx)) != 0)
+ goto fail;
+ }
+ }
+
+ assert(remaining == 0 && keyProgress == (key.data + key.length));
+ err = noErr;
+fail:
+ SSLFreeBuffer(md5Context, ctx);
+ SSLFreeBuffer(shaContext, ctx);
+
+ #if LOG_GEN_KEY
+ printf("GenerateKey: DONE\n");
+ #endif
+ return err;
+}
+
+static OSStatus ssl3GenerateExportKeyAndIv (
+ SSLContext *ctx, // clientRandom, serverRandom valid
+ const SSLBuffer clientWriteKey,
+ const SSLBuffer serverWriteKey,
+ SSLBuffer finalClientWriteKey, // RETURNED, mallocd by caller
+ SSLBuffer finalServerWriteKey, // RETURNED, mallocd by caller
+ SSLBuffer finalClientIV, // RETURNED, mallocd by caller
+ SSLBuffer finalServerIV) // RETURNED, mallocd by caller
+{
+ OSStatus err;
+ SSLBuffer hashCtx, serverRandom, clientRandom;
+
+ /* random blobs are 32 bytes */
+ serverRandom.data = ctx->serverRandom;
+ serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ clientRandom.data = ctx->clientRandom;
+ clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+
+ if ((err = SSLAllocBuffer(hashCtx, SSLHashMD5.contextSize, ctx)) != 0)
+ return err;
+ /* client write key */
+ if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, clientWriteKey)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ finalClientWriteKey.length = 16;
+ if ((err = SSLHashMD5.final(hashCtx, finalClientWriteKey)) != 0)
+ goto fail;
+
+ /* optional client IV */
+ if (ctx->selectedCipherSpec->cipher->ivSize > 0)
+ { if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ finalClientIV.length = 16;
+ if ((err = SSLHashMD5.final(hashCtx, finalClientIV)) != 0)
+ goto fail;
+ }
+
+ /* server write key */
+ if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, serverWriteKey)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ finalServerWriteKey.length = 16;
+ if ((err = SSLHashMD5.final(hashCtx, finalServerWriteKey)) != 0)
+ goto fail;
+
+ /* optional server IV */
+ if (ctx->selectedCipherSpec->cipher->ivSize > 0)
+ { if ((err = SSLHashMD5.init(hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ finalServerIV.length = 16;
+ if ((err = SSLHashMD5.final(hashCtx, finalServerIV)) != 0)
+ goto fail;
+ }
+
+ err = noErr;
+fail:
+ SSLFreeBuffer(hashCtx, ctx);
+ return err;
+}
+
+/*
+ * On entry: clientRandom, serverRandom, preMasterSecret valid
+ * On return: masterSecret valid
+ */
+static OSStatus ssl3GenerateMasterSecret (
+ SSLContext *ctx)
+{
+ OSStatus err;
+ SSLBuffer shaState, md5State, clientRandom,
+ serverRandom, shaHash, md5Hash, leader;
+ UInt8 *masterProgress, shaHashData[20], leaderData[3];
+ int i;
+
+ md5State.data = shaState.data = 0;
+ if ((err = SSLAllocBuffer(md5State, SSLHashMD5.contextSize, ctx)) != 0)
+ goto fail;
+ if ((err = SSLAllocBuffer(shaState, SSLHashSHA1.contextSize, ctx)) != 0)
+ goto fail;
+
+ clientRandom.data = ctx->clientRandom;
+ clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ serverRandom.data = ctx->serverRandom;
+ serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ shaHash.data = shaHashData;
+ shaHash.length = 20;
+
+ masterProgress = ctx->masterSecret;
+
+ for (i = 1; i <= 3; i++)
+ { if ((err = SSLHashMD5.init(md5State, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.init(shaState, ctx)) != 0)
+ goto fail;
+
+ leaderData[0] = leaderData[1] = leaderData[2] = 0x40 + i; /* 'A', 'B', etc. */
+ leader.data = leaderData;
+ leader.length = i;
+
+ if ((err = SSLHashSHA1.update(shaState, leader)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(shaState, ctx->preMasterSecret)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(shaState, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(shaState, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.final(shaState, shaHash)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(md5State, ctx->preMasterSecret)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(md5State, shaHash)) != 0)
+ goto fail;
+ md5Hash.data = masterProgress;
+ md5Hash.length = 16;
+ if ((err = SSLHashMD5.final(md5State, md5Hash)) != 0)
+ goto fail;
+ masterProgress += 16;
+ }
+
+ err = noErr;
+fail:
+ SSLFreeBuffer(shaState, ctx);
+ SSLFreeBuffer(md5State, ctx);
+ return err;
+}
+
+/* common routine to compute a Mac for finished message and cert verify message */
+static OSStatus
+ssl3CalculateFinishedMessage(
+ SSLContext *ctx,
+ SSLBuffer finished, // mallocd by caller
+ SSLBuffer shaMsgState, // running total
+ SSLBuffer md5MsgState, // ditto
+ UInt32 senderID) // optional, nonzero for finished message
+{
+ OSStatus err;
+ SSLBuffer hash, input;
+ UInt8 sender[4], md5Inner[16], shaInner[20];
+
+ // assert(finished.length == 36);
+
+ if (senderID != 0) {
+ SSLEncodeInt(sender, senderID, 4);
+ input.data = sender;
+ input.length = 4;
+ if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+ return err;
+ if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+ return err;
+ }
+ input.data = ctx->masterSecret;
+ input.length = SSL_MASTER_SECRET_SIZE;
+ if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+ return err;
+ if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+ return err;
+ input.data = (UInt8 *)SSLMACPad1;
+ input.length = SSLHashMD5.macPadSize;
+ if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+ return err;
+ input.length = SSLHashSHA1.macPadSize;
+ if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+ return err;
+ hash.data = md5Inner;
+ hash.length = 16;
+ if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
+ return err;
+ hash.data = shaInner;
+ hash.length = 20;
+ if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
+ return err;
+ if ((err = SSLHashMD5.init(md5MsgState, ctx)) != 0)
+ return err;
+ if ((err = SSLHashSHA1.init(shaMsgState, ctx)) != 0)
+ return err;
+ input.data = ctx->masterSecret;
+ input.length = SSL_MASTER_SECRET_SIZE;
+ if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+ return err;
+ if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+ return err;
+ input.data = (UInt8 *)SSLMACPad2;
+ input.length = SSLHashMD5.macPadSize;
+ if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+ return err;
+ input.length = SSLHashSHA1.macPadSize;
+ if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+ return err;
+ input.data = md5Inner;
+ input.length = 16;
+ if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+ return err;
+ hash.data = finished.data;
+ hash.length = 16;
+ if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
+ return err;
+ input.data = shaInner;
+ input.length = 20;
+ if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+ return err;
+ hash.data = finished.data + 16;
+ hash.length = 20;
+ if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
+ return err;
+ return noErr;
+}
+
+
+static OSStatus ssl3ComputeFinishedMac (
+ SSLContext *ctx,
+ SSLBuffer finished, // output - mallocd by caller
+ SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
+ SSLBuffer md5MsgState, // ditto
+ Boolean isServer) // refers to message, not us
+{
+ return ssl3CalculateFinishedMessage(ctx, finished, shaMsgState, md5MsgState,
+ isServer ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client);
+}
+
+static OSStatus ssl3ComputeCertVfyMac (
+ SSLContext *ctx,
+ SSLBuffer finished, // output - mallocd by caller
+ SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
+ SSLBuffer md5MsgState) // ditto
+{
+ return ssl3CalculateFinishedMessage(ctx, finished, shaMsgState, md5MsgState, 0);
+}
+
+const SslTlsCallouts Ssl3Callouts = {
+ ssl3DecryptRecord,
+ ssl3WriteRecord,
+ ssl3InitMac,
+ ssl3FreeMac,
+ ssl3ComputeMac,
+ ssl3GenerateKeyMaterial,
+ ssl3GenerateExportKeyAndIv,
+ ssl3GenerateMasterSecret,
+ ssl3ComputeFinishedMac,
+ ssl3ComputeCertVfyMac
+};
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/* *********************************************************************
+ File: sslAlertMessage.cpp - SSL3 Alert protocol
+ ****************************************************************** */
+
+#include "ssl.h"
+#include "sslAlertMessage.h"
+#include "sslMemory.h"
+#include "sslContext.h"
+#include "sslSession.h"
+#include "sslDebug.h"
+
+#include <assert.h>
+
+#ifdef NDEBUG
+#define SSLLogAlertMsg(msg,sent)
+#else
+static void SSLLogAlertMsg(AlertDescription msg, bool sent);
+#endif
+
+OSStatus
+SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
+{ OSStatus err = noErr;
+ AlertLevel level;
+ AlertDescription desc;
+ uint8 *charPtr;
+ uint32 remaining;
+
+ if (rec.contents.length % 2 != 0)
+ {
+ err = SSLFatalSessionAlert(SSL_AlertIllegalParam, ctx);
+ if (!err) {
+ err = errSSLProtocol;
+ }
+ return err;
+ }
+
+ charPtr = rec.contents.data;
+ remaining = rec.contents.length;
+ while (remaining > 0)
+ { level = (AlertLevel)*charPtr++;
+ desc = (AlertDescription)*charPtr++;
+ sslHdskMsgDebug("alert msg recieved level %d desc %d\n",
+ (int)level, (int)desc);
+ remaining -= 2;
+ SSLLogAlertMsg(desc, false);
+
+ /*
+ * Ignore sessionID-related failures here;
+ * the important thing is the alert.
+ */
+ if (level == SSL_AlertLevelFatal)
+ {
+ SSLDeleteSessionData(ctx);
+ sslErrorLog("***Fatal alert %d received\n", desc);
+ return errSSLFatalAlert;
+ }
+
+ switch (desc)
+ { case SSL_AlertUnexpectedMsg:
+ case SSL_AlertBadRecordMac:
+ case SSL_AlertDecompressFail:
+ case SSL_AlertHandshakeFail:
+ case SSL_AlertIllegalParam:
+ /* These must always be fatal; if we got here, the level is warning;
+ * die anyway
+ */
+ SSLDeleteSessionData(ctx);
+ err = errSSLFatalAlert;
+ break;
+ case SSL_AlertCloseNotify:
+ SSLClose(ctx);
+ err = noErr;
+ break;
+ case SSL_AlertNoCert:
+ if((ctx->state == SSL_HdskStateClientCert) &&
+ (ctx->protocolSide == SSL_ServerSide) &&
+ (ctx->clientAuth != kAlwaysAuthenticate)) {
+ /*
+ * Tolerate this unless we're configured to
+ * *require* a client cert. If a client cert is
+ * required, we'll catch the error at the next
+ * handshake msg we receive - which will probably
+ * be a client key exchange msg, which is illegal
+ * when we're in state SSL_HdskStateClientCert.
+ * If the client cert is optional, advance to
+ * state ClientKeyExchange by pretending we
+ * just got a client cert msg.
+ */
+ if ((err = SSLAdvanceHandshake(SSL_HdskCert,
+ ctx)) != 0) {
+ return err;
+ }
+ }
+ break;
+ case SSL_AlertBadCert:
+ case SSL_AlertUnsupportedCert:
+ case SSL_AlertCertRevoked:
+ case SSL_AlertCertExpired:
+ case SSL_AlertCertUnknown:
+ err = noErr;
+ break;
+ default:
+ /* Unknown alert, but not fatal; ignore it */
+ break;
+ }
+ }
+
+ return err;
+}
+
+OSStatus
+SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx)
+{ SSLRecord rec;
+ OSStatus err;
+
+ assert((ctx->negProtocolVersion != SSL_Version_2_0));
+
+ if ((err = SSLEncodeAlert(rec, level, desc, ctx)) != 0)
+ return err;
+ assert(ctx->sslTslCalls != NULL);
+ SSLLogAlertMsg(desc, true);
+ if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+ return err;
+ if ((err = SSLFreeBuffer(rec.contents, ctx)) != 0)
+ return err;
+
+ return noErr;
+}
+
+OSStatus
+SSLEncodeAlert(SSLRecord &rec, AlertLevel level, AlertDescription desc, SSLContext *ctx)
+{ OSStatus err;
+
+ rec.contentType = SSL_RecordTypeAlert;
+ assert((ctx->negProtocolVersion != SSL_Version_2_0));
+ if(ctx->negProtocolVersion == SSL_Version_Undetermined) {
+ /* error while negotiating */
+ rec.protocolVersion = ctx->maxProtocolVersion;
+ }
+ else {
+ rec.protocolVersion = ctx->negProtocolVersion;
+ }
+ rec.contents.length = 2;
+ if ((err = SSLAllocBuffer(rec.contents, 2, ctx)) != 0)
+ return err;
+ rec.contents.data[0] = level;
+ rec.contents.data[1] = desc;
+
+ return noErr;
+}
+
+OSStatus
+SSLFatalSessionAlert(AlertDescription desc, SSLContext *ctx)
+{ OSStatus err1, err2;
+
+ if(desc != SSL_AlertCloseNotify) {
+ sslErrorLog("SSLFatalSessionAlert: desc %d\n", desc);
+ }
+ SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
+
+ /* Make session unresumable; I'm not stopping if I get an error,
+ because I'd like to attempt to send the alert anyway */
+ err1 = SSLDeleteSessionData(ctx);
+
+ /* Second, send the alert */
+ err2 = SSLSendAlert(SSL_AlertLevelFatal, desc, ctx);
+
+ /* If they both returned errors, arbitrarily return the first */
+ return err1 != 0 ? err1 : err2;
+}
+
+#ifndef NDEBUG
+
+/* log alert messages */
+
+static char *alertMsgToStr(AlertDescription msg)
+{
+ static char badStr[100];
+
+ switch(msg) {
+ case SSL_AlertCloseNotify:
+ return "SSL_AlertCloseNotify";
+ case SSL_AlertUnexpectedMsg:
+ return "SSL_AlertUnexpectedMsg";
+ case SSL_AlertBadRecordMac:
+ return "SSL_AlertBadRecordMac";
+ case SSL_AlertDecryptionFail:
+ return "SSL_AlertDecryptionFail";
+ case SSL_AlertRecordOverflow:
+ return "SSL_AlertRecordOverflow";
+ case SSL_AlertDecompressFail:
+ return "SSL_AlertDecompressFail";
+ case SSL_AlertHandshakeFail:
+ return "SSL_AlertHandshakeFail";
+ case SSL_AlertNoCert:
+ return "SSL_AlertNoCert";
+ case SSL_AlertBadCert:
+ return "SSL_AlertBadCert";
+ case SSL_AlertUnsupportedCert:
+ return "SSL_AlertUnsupportedCert";
+ case SSL_AlertCertRevoked:
+ return "SSL_AlertCertRevoked";
+
+ case SSL_AlertCertExpired:
+ return "SSL_AlertCertExpired";
+ case SSL_AlertCertUnknown:
+ return "SSL_AlertCertUnknown";
+ case SSL_AlertIllegalParam:
+ return "SSL_AlertIllegalParam";
+ case SSL_AlertUnknownCA:
+ return "SSL_AlertUnknownCA";
+ case SSL_AlertAccessDenied:
+ return "SSL_AlertAccessDenied";
+ case SSL_AlertDecodeError:
+ return "SSL_AlertDecodeError";
+ case SSL_AlertDecryptError:
+ return "SSL_AlertDecryptError";
+
+ case SSL_AlertExportRestriction:
+ return "SSL_AlertExportRestriction";
+ case SSL_AlertProtocolVersion:
+ return "SSL_AlertProtocolVersion";
+ case SSL_AlertInsufficientSecurity:
+ return "SSL_AlertInsufficientSecurity";
+ case SSL_AlertInternalError:
+ return "SSL_AlertInternalError";
+ case SSL_AlertUserCancelled:
+ return "SSL_AlertUserCancelled";
+ case SSL_AlertNoRenegotiation:
+ return "SSL_AlertNoRenegotiation";
+
+ default:
+ sprintf(badStr, "Unknown state (%d(d)", msg);
+ return badStr;
+ }
+}
+
+static void SSLLogAlertMsg(AlertDescription msg, bool sent)
+{
+ sslHdskMsgDebug("---%s alert msg %s",
+ alertMsgToStr(msg), (sent ? "sent" : "recv"));
+}
+
+#endif /* NDEBUG */
*/
#include "ssl.h"
-#include "sslalloc.h"
+#include "sslMemory.h"
#include "sslDebug.h"
#include "sslBER.h"
* publicExponent INTEGER -- e }
*/
-SSLErr sslDecodeRsaBlob(
+OSStatus sslDecodeRsaBlob(
const SSLBuffer *blob, /* PKCS-1 encoded */
SSLBuffer *modulus, /* data mallocd and RETURNED */
SSLBuffer *exponent) /* data mallocd and RETURNED */
{
- SSLErr srtn;
+ OSStatus srtn;
- CASSERT(blob != NULL);
- CASSERT(modulus != NULL);
- CASSERT(exponent != NULL);
+ assert(blob != NULL);
+ assert(modulus != NULL);
+ assert(exponent != NULL);
/* DER-decode the blob */
RSAPublicKey snaccPubKey;
SC_decodeAsnObj(cssmBlob, snaccPubKey);
}
catch(...) {
- return SSLBadCert;
+ return errSSLBadCert;
}
/* malloc & convert components */
- srtn = SSLAllocBuffer(modulus, snaccPubKey.modulus.Len(), NULL);
+ srtn = SSLAllocBuffer(*modulus, snaccPubKey.modulus.Len(), NULL);
if(srtn) {
return srtn;
}
snaccIntToData(snaccPubKey.modulus, modulus);
- srtn = SSLAllocBuffer(exponent, snaccPubKey.publicExponent.Len(),
+ srtn = SSLAllocBuffer(*exponent, snaccPubKey.publicExponent.Len(),
NULL);
if(srtn) {
return srtn;
}
snaccIntToData(snaccPubKey.publicExponent, exponent);
- return SSLNoErr;
+ return noErr;
}
/*
* Given a raw modulus and exponent, cook up a
* BER-encoded RSA public key blob.
*/
-SSLErr sslEncodeRsaBlob(
+OSStatus sslEncodeRsaBlob(
const SSLBuffer *modulus,
const SSLBuffer *exponent,
SSLBuffer *blob) /* data mallocd and RETURNED */
{
- CASSERT((modulus != NULL) && (exponent != NULL));
+ assert((modulus != NULL) && (exponent != NULL));
blob->data = NULL;
blob->length = 0;
}
catch(...) {
/* right...? */
- return SSLMemoryErr;
+ return memFullErr;
}
/* copy to caller's SSLBuffer */
- SSLErr srtn = SSLAllocBuffer(blob, cblob.length(), NULL);
+ OSStatus srtn = SSLAllocBuffer(*blob, cblob.length(), NULL);
if(srtn) {
return srtn;
}
memmove(blob->data, cblob.data(), cblob.length());
- return SSLNoErr;
+ return noErr;
}
+++ /dev/null
-
-/*
- File: sslBER_Dummy.cpp
-
- Contains: stubs of routines in sslBER.cpp to enable standalone
- build for indexing purposes.
-
- Written by: Doug Mitchell
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-#include "ssl.h"
-#include "sslalloc.h"
-#include "sslDebug.h"
-#include "sslBER.h"
-
-#include <string.h>
-
-/*
- * Given a PKCS-1 encoded RSA public key, extract the
- * modulus and public exponent.
- *
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER -- e }
- */
-
-SSLErr sslDecodeRsaBlob(
- const SSLBuffer *blob, /* PKCS-1 encoded */
- SSLBuffer *modulus, /* data mallocd and RETURNED */
- SSLBuffer *exponent) /* data mallocd and RETURNED */
-{
- return SSLBadCert;
-}
-
-/*
- * Given a raw modulus and exponent, cook up a
- * BER-encoded RSA public key blob.
- */
-SSLErr sslEncodeRsaBlob(
- const SSLBuffer *modulus,
- const SSLBuffer *exponent,
- SSLBuffer *blob) /* data mallocd and RETURNED */
-{
- return SSLMemoryErr;
-}
-
--- /dev/null
+
+/*
+ File: sslBER_Dummy.cpp
+
+ Contains: stubs of routines in sslBER.cpp to enable standalone
+ build for indexing purposes. Unlike the real sslBER.cpp,
+ this version does not require the SecurityANS1 files
+ (which are not exported from Security.framework).
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "sslMemory.h"
+#include "sslDebug.h"
+#include "sslBER.h"
+
+#include <string.h>
+
+/*
+ * Given a PKCS-1 encoded RSA public key, extract the
+ * modulus and public exponent.
+ *
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER -- e }
+ */
+
+OSStatus sslDecodeRsaBlob(
+ const SSLBuffer *blob, /* PKCS-1 encoded */
+ SSLBuffer *modulus, /* data mallocd and RETURNED */
+ SSLBuffer *exponent) /* data mallocd and RETURNED */
+{
+ return errSSLBadCert;
+}
+
+/*
+ * Given a raw modulus and exponent, cook up a
+ * BER-encoded RSA public key blob.
+ */
+OSStatus sslEncodeRsaBlob(
+ const SSLBuffer *modulus,
+ const SSLBuffer *exponent,
+ SSLBuffer *blob) /* data mallocd and RETURNED */
+{
+ return errSSLCrypto;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslCert.cpp
+
+ Contains: certificate request/verify messages
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslMemory.h"
+#include "sslAlertMessage.h"
+#include "sslDebug.h"
+#include "sslUtils.h"
+#include "sslDigests.h"
+#include "appleCdsa.h"
+
+#include <string.h>
+#include <assert.h>
+
+OSStatus
+SSLEncodeCertificate(SSLRecord &certificate, SSLContext *ctx)
+{ OSStatus err;
+ UInt32 totalLength;
+ int i, j, certCount;
+ UInt8 *charPtr;
+ SSLCertificate *cert;
+
+ /*
+ * TBD: for client side, match Match DER-encoded acceptable DN list
+ * (ctx->acceptableDNList) to one of our certs. For now we just send
+ * what we have since we don't support multiple certs.
+ *
+ * Note this can be called with localCert==0 for client seide in TLS1;
+ * in that case we send an empty cert msg.
+ */
+ cert = ctx->localCert;
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ assert((cert != NULL) || (ctx->negProtocolVersion == TLS_Version_1_0));
+ totalLength = 0;
+ certCount = 0;
+ while (cert)
+ { totalLength += 3 + cert->derCert.length; /* 3 for encoded length field */
+ ++certCount;
+ cert = cert->next;
+ }
+
+ certificate.contentType = SSL_RecordTypeHandshake;
+ certificate.protocolVersion = ctx->negProtocolVersion;
+ if ((err = SSLAllocBuffer(certificate.contents, totalLength + 7, ctx)) != 0)
+ return err;
+
+ charPtr = certificate.contents.data;
+ *charPtr++ = SSL_HdskCert;
+ charPtr = SSLEncodeInt(charPtr, totalLength+3, 3); /* Handshake message length */
+ charPtr = SSLEncodeInt(charPtr, totalLength, 3); /* Vector length */
+
+ /* Root cert is first in the linked list, but has to go last,
+ * so walk list backwards */
+ for (i = 0; i < certCount; ++i)
+ { cert = ctx->localCert;
+ for (j = i+1; j < certCount; ++j)
+ cert = cert->next;
+ charPtr = SSLEncodeInt(charPtr, cert->derCert.length, 3);
+ memcpy(charPtr, cert->derCert.data, cert->derCert.length);
+ charPtr += cert->derCert.length;
+ }
+
+ assert(charPtr == certificate.contents.data + certificate.contents.length);
+
+ if ((ctx->protocolSide == SSL_ClientSide) && (ctx->localCert)) {
+ /* this tells us to send a CertificateVerify msg after the
+ * client key exchange. We skip the cert vfy if we just
+ * sent an empty cert msg (i.e., we were asked for a cert
+ * but we don't have one). */
+ ctx->certSent = 1;
+ assert(ctx->clientCertState == kSSLClientCertRequested);
+ assert(ctx->certRequested);
+ ctx->clientCertState = kSSLClientCertSent;
+ }
+ return noErr;
+}
+
+OSStatus
+SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
+{ OSStatus err;
+ UInt32 listLen, certLen;
+ UInt8 *p;
+ SSLCertificate *cert;
+
+ p = message.data;
+ listLen = SSLDecodeInt(p,3);
+ p += 3;
+ if (listLen + 3 != message.length) {
+ sslErrorLog("SSLProcessCertificate: length decode error 1\n");
+ return errSSLProtocol;
+ }
+
+ while (listLen > 0)
+ { certLen = SSLDecodeInt(p,3);
+ p += 3;
+ if (listLen < certLen + 3) {
+ sslErrorLog("SSLProcessCertificate: length decode error 2\n");
+ return errSSLProtocol;
+ }
+ cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
+ if(cert == NULL) {
+ return memFullErr;
+ }
+ if ((err = SSLAllocBuffer(cert->derCert, certLen, ctx)) != 0)
+ { sslFree(cert);
+ return err;
+ }
+ memcpy(cert->derCert.data, p, certLen);
+ p += certLen;
+ cert->next = ctx->peerCert; /* Insert backwards; root cert
+ * will be first in linked list */
+ ctx->peerCert = cert;
+ listLen -= 3+certLen;
+ }
+ assert(p == message.data + message.length && listLen == 0);
+
+ if (ctx->peerCert == 0) {
+ /* this *might* be OK... */
+ if((ctx->protocolSide == SSL_ServerSide) &&
+ (ctx->clientAuth != kAlwaysAuthenticate)) {
+ /*
+ * we tried to authenticate, client doesn't have a cert, and
+ * app doesn't require it. OK.
+ */
+ return noErr;
+ }
+ else {
+ return errSSLXCertChainInvalid;
+ }
+ }
+ if((err = sslVerifyCertChain(ctx, *ctx->peerCert)) != 0)
+ return err;
+
+ /* peer's certificate is the last one in the chain */
+ cert = ctx->peerCert;
+ while (cert->next != 0)
+ cert = cert->next;
+ /* Convert its public key to CDSA format */
+ if ((err = sslPubKeyFromCert(ctx,
+ cert->derCert,
+ &ctx->peerPubKey,
+ &ctx->peerPubKeyCsp)) != 0)
+ return err;
+
+ return noErr;
+}
+
+OSStatus
+SSLEncodeCertificateRequest(SSLRecord &request, SSLContext *ctx)
+{
+ OSStatus err;
+ UInt32 dnListLen, msgLen;
+ UInt8 *charPtr;
+ DNListElem *dn;
+
+ assert(ctx->protocolSide == SSL_ServerSide);
+ dnListLen = 0;
+ dn = ctx->acceptableDNList;
+ while (dn)
+ { dnListLen += 2 + dn->derDN.length;
+ dn = dn->next;
+ }
+ msgLen = 1 + 1 + 2 + dnListLen;
+
+ request.contentType = SSL_RecordTypeHandshake;
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ request.protocolVersion = ctx->negProtocolVersion;
+ if ((err = SSLAllocBuffer(request.contents, msgLen + 4, ctx)) != 0)
+ return err;
+
+ charPtr = request.contents.data;
+ *charPtr++ = SSL_HdskCertRequest;
+ charPtr = SSLEncodeInt(charPtr, msgLen, 3);
+
+ *charPtr++ = 1; /* one cert type */
+ *charPtr++ = 1; /* RSA-sign type */
+ charPtr = SSLEncodeInt(charPtr, dnListLen, 2);
+ dn = ctx->acceptableDNList;
+ while (dn)
+ { charPtr = SSLEncodeInt(charPtr, dn->derDN.length, 2);
+ memcpy(charPtr, dn->derDN.data, dn->derDN.length);
+ charPtr += dn->derDN.length;
+ dn = dn->next;
+ }
+
+ assert(charPtr == request.contents.data + request.contents.length);
+ return noErr;
+}
+
+OSStatus
+SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx)
+{
+ unsigned i;
+ unsigned typeCount;
+ UInt8 *charPtr;
+
+ /*
+ * Cert request only happens in during client authentication, which
+ * we don't do. We will however take this handshake msg and do
+ * nothing with the enclosed DNList. We'll send a client cert
+ * if we have one but we don't do any DNList compare.
+ */
+ if (message.length < 3) {
+ sslErrorLog("SSLProcessCertificateRequest: length decode error 1\n");
+ return errSSLProtocol;
+ }
+ charPtr = message.data;
+ typeCount = *charPtr++;
+ if (typeCount < 1 || message.length < 3 + typeCount) {
+ sslErrorLog("SSLProcessCertificateRequest: length decode error 2\n");
+ return errSSLProtocol;
+ }
+ for (i = 0; i < typeCount; i++)
+ { if (*charPtr++ == 1)
+ ctx->x509Requested = 1;
+ }
+
+ #if 0
+ /* FIXME - currently untested */
+ unsigned dnListLen;
+ unsigned dnLen;
+ SSLBuffer dnBuf;
+ DNListElem *dn;
+ OSStatus err;
+
+ dnListLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ if (message.length != 3 + typeCount + dnListLen) {
+ sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n");
+ return errSSLProtocol;
+ }
+ while (dnListLen > 0)
+ { if (dnListLen < 2) {
+ sslErrorLog("SSLProcessCertificateRequest: dnListLen error 1\n");
+ return errSSLProtocol;
+ }
+ dnLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ if (dnListLen < 2 + dnLen) {
+ sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n");
+ return errSSLProtocol;
+ }
+ if ((err = SSLAllocBuffer(dnBuf, sizeof(DNListElem), ctx)) != 0)
+ return err;
+ dn = (DNListElem*)dnBuf.data;
+ if ((err = SSLAllocBuffer(dn->derDN, dnLen, ctx)) != 0)
+ { SSLFreeBuffer(dnBuf, ctx);
+ return err;
+ }
+ memcpy(dn->derDN.data, charPtr, dnLen);
+ charPtr += dnLen;
+ dn->next = ctx->acceptableDNList;
+ ctx->acceptableDNList = dn;
+ dnListLen -= 2 + dnLen;
+ }
+
+ assert(charPtr == message.data + message.length);
+ #endif /* untested client-side authentication */
+
+ return noErr;
+}
+
+OSStatus
+SSLEncodeCertificateVerify(SSLRecord &certVerify, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 hashData[36];
+ SSLBuffer hashDataBuf, shaMsgState, md5MsgState;
+ UInt32 len;
+ UInt32 outputLen;
+
+ certVerify.contents.data = 0;
+ hashDataBuf.data = hashData;
+ hashDataBuf.length = 36;
+
+ if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
+ goto fail;
+ if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
+ goto fail;
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, hashDataBuf,
+ shaMsgState, md5MsgState)) != 0)
+ goto fail;
+
+ assert(ctx->signingPrivKey != NULL);
+ len = sslKeyLengthInBytes(ctx->signingPrivKey);
+
+ certVerify.contentType = SSL_RecordTypeHandshake;
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ certVerify.protocolVersion = ctx->negProtocolVersion;
+ if ((err = SSLAllocBuffer(certVerify.contents, len + 6, ctx)) != 0)
+ goto fail;
+
+ certVerify.contents.data[0] = SSL_HdskCertVerify;
+ SSLEncodeInt(certVerify.contents.data+1, len+2, 3);
+ SSLEncodeInt(certVerify.contents.data+4, len, 2);
+
+ err = sslRsaRawSign(ctx,
+ ctx->signingPrivKey,
+ ctx->signingKeyCsp,
+ hashData, // data to sign
+ 36, // MD5 size + SHA1 size
+ certVerify.contents.data+6, // signature destination
+ len, // we mallocd len+6
+ &outputLen);
+ if(err) {
+ goto fail;
+ }
+
+ assert(outputLen == len);
+
+ err = noErr;
+
+fail:
+ SSLFreeBuffer(shaMsgState, ctx);
+ SSLFreeBuffer(md5MsgState, ctx);
+
+ return err;
+}
+
+OSStatus
+SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 hashData[36];
+ UInt16 signatureLen;
+ SSLBuffer hashDataBuf, shaMsgState, md5MsgState;
+ unsigned int publicModulusLen;
+
+ shaMsgState.data = 0;
+ md5MsgState.data = 0;
+
+ if (message.length < 2) {
+ sslErrorLog("SSLProcessCertificateVerify: msg len error\n");
+ return errSSLProtocol;
+ }
+
+ signatureLen = (UInt16)SSLDecodeInt(message.data, 2);
+ if (message.length != (unsigned)(2 + signatureLen)) {
+ sslErrorLog("SSLProcessCertificateVerify: sig len error 1\n");
+ return errSSLProtocol;
+ }
+
+ assert(ctx->peerPubKey != NULL);
+ publicModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
+
+ if (signatureLen != publicModulusLen) {
+ sslErrorLog("SSLProcessCertificateVerify: sig len error 2\n");
+ return errSSLProtocol;
+ }
+ hashDataBuf.data = hashData;
+ hashDataBuf.length = 36;
+
+ if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
+ goto fail;
+ if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
+ goto fail;
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, hashDataBuf,
+ shaMsgState, md5MsgState)) != 0)
+ goto fail;
+
+ /*
+ * The CSP does the decrypt & compare for us in one shot
+ */
+ err = sslRsaRawVerify(ctx,
+ ctx->peerPubKey,
+ ctx->peerPubKeyCsp, // FIXME - maybe we just use cspHand?
+ hashData, // data to verify
+ 36,
+ message.data + 2, // signature
+ signatureLen);
+ if(err) {
+ goto fail;
+ }
+ err = noErr;
+
+fail:
+ SSLFreeBuffer(shaMsgState, ctx);
+ SSLFreeBuffer(md5MsgState, ctx);
+
+ return err;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslChangeCipher.cpp
+
+ Contains: support for change cipher spec messages
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslMemory.h"
+#include "sslAlertMessage.h"
+#include "sslDebug.h"
+
+#include <assert.h>
+#include <string.h>
+
+OSStatus
+SSLEncodeChangeCipherSpec(SSLRecord &rec, SSLContext *ctx)
+{ OSStatus err;
+
+ assert(ctx->writePending.ready);
+
+ sslLogNegotiateDebug("===Sending changeCipherSpec msg");
+ rec.contentType = SSL_RecordTypeChangeCipher;
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ rec.protocolVersion = ctx->negProtocolVersion;
+ rec.contents.length = 1;
+ if ((err = SSLAllocBuffer(rec.contents, 1, ctx)) != 0)
+ return err;
+ rec.contents.data[0] = 1;
+
+ return noErr;
+}
+
+OSStatus
+SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx)
+{ OSStatus err;
+
+ if (rec.contents.length != 1 || rec.contents.data[0] != 1)
+ { SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ sslErrorLog("***bad changeCipherSpec msg: length %d data 0x%x\n",
+ (unsigned)rec.contents.length, (unsigned)rec.contents.data[0]);
+ return errSSLProtocol;
+ }
+
+ if (!ctx->readPending.ready || ctx->state != SSL_HdskStateChangeCipherSpec)
+ { SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ sslErrorLog("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
+ (unsigned)ctx->readPending.ready, (unsigned)ctx->state);
+ return errSSLProtocol;
+ }
+
+ sslLogNegotiateDebug("===Processing changeCipherSpec msg");
+
+ /* Install new cipher spec on read side */
+ if ((err = SSLDisposeCipherSuite(&ctx->readCipher, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ ctx->readCipher = ctx->readPending;
+ ctx->readCipher.ready = 0; /* Can't send data until Finished is sent */
+ SSLChangeHdskState(ctx, SSL_HdskStateFinished);
+ memset(&ctx->readPending, 0, sizeof(CipherContext)); /* Zero out old data */
+ return noErr;
+}
+
+OSStatus
+SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx)
+{ OSStatus err;
+
+ /* symmetric key */
+ if (cipher->symKey)
+ { if ((err = cipher->symCipher->finish(cipher, ctx)) != 0)
+ return err;
+ cipher->symKey = 0;
+ }
+
+ /* per-record hash/hmac context */
+ ctx->sslTslCalls->freeMac(cipher);
+
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslContext.cpp
+
+ Contains: SSLContext accessors
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "sslContext.h"
+#include "sslMemory.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include "sslDigests.h"
+#include "sslDebug.h"
+#include "appleCdsa.h"
+#include "sslKeychain.h"
+#include "sslUtils.h"
+#include "cipherSpecs.h"
+#include "appleSession.h"
+#include <string.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecTrust.h>
+
+static void sslFreeDnList(
+ SSLContext *ctx)
+{
+ DNListElem *dn, *nextDN;
+
+ dn = ctx->acceptableDNList;
+ while (dn)
+ {
+ SSLFreeBuffer(dn->derDN, ctx);
+ nextDN = dn->next;
+ sslFree(dn);
+ dn = nextDN;
+ }
+ ctx->acceptableDNList = NULL;
+}
+
+static OSStatus sslFreeTrustedRoots(
+ SSLContext *ctx)
+{
+ unsigned i;
+
+ assert(ctx != NULL);
+ if((ctx->numTrustedCerts == 0) || (ctx->trustedCerts == NULL)) {
+ /* they really should both be zero, right? */
+ assert((ctx->numTrustedCerts == 0) && (ctx->trustedCerts == NULL));
+ }
+ else {
+ for(i=0; i<ctx->numTrustedCerts; i++) {
+ stFreeCssmData(&ctx->trustedCerts[i], CSSM_FALSE);
+ }
+ sslFree(ctx->trustedCerts);
+ }
+ ctx->numTrustedCerts = 0;
+ ctx->trustedCerts = NULL;
+ sslFreeDnList(ctx);
+ return noErr;
+}
+
+/*
+ * Default attempted version.
+ */
+#define DEFAULT_MAX_VERSION TLS_Version_1_0
+
+OSStatus
+SSLNewContext (Boolean isServer,
+ SSLContextRef *contextPtr) /* RETURNED */
+{
+ SSLContext *ctx;
+ OSStatus serr;
+
+ if(contextPtr == NULL) {
+ return paramErr;
+ }
+ *contextPtr = NULL;
+ ctx = (SSLContext *)sslMalloc(sizeof(SSLContext));
+ if(ctx == NULL) {
+ return memFullErr;
+ }
+ /* subsequent errors to errOut: */
+
+ memset(ctx, 0, sizeof(SSLContext));
+ ctx->state = SSL_HdskStateUninit;
+ ctx->clientCertState = kSSLClientCertNone;
+
+ /* different defaults for client and server ... */
+ if(isServer) {
+ ctx->protocolSide = SSL_ServerSide;
+ ctx->reqProtocolVersion = DEFAULT_MAX_VERSION;
+ }
+ else {
+ ctx->protocolSide = SSL_ClientSide;
+ ctx->reqProtocolVersion = SSL_Version_Undetermined;
+ }
+ ctx->negProtocolVersion = SSL_Version_Undetermined;
+ ctx->maxProtocolVersion = DEFAULT_MAX_VERSION;
+ /* Default value so we can send and receive hello msgs */
+ ctx->sslTslCalls = &Ssl3Callouts;
+
+ /* Initialize the cipher state to NULL_WITH_NULL_NULL */
+ ctx->selectedCipherSpec = &SSL_NULL_WITH_NULL_NULL_CipherSpec;
+ ctx->selectedCipher = ctx->selectedCipherSpec->cipherSpec;
+ ctx->writeCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
+ ctx->readCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
+ ctx->readCipher.symCipher = ctx->selectedCipherSpec->cipher;
+ ctx->writeCipher.symCipher = ctx->selectedCipherSpec->cipher;
+
+ /* these two are invariant */
+ ctx->writeCipher.encrypting = 1;
+ ctx->writePending.encrypting = 1;
+
+ /* this gets init'd on first call to SSLHandshake() */
+ ctx->validCipherSpecs = NULL;
+ ctx->numValidCipherSpecs = 0;
+
+ ctx->peerDomainName = NULL;
+ ctx->peerDomainNameLen = 0;
+
+ /* attach to CSP, CL, TP */
+ serr = attachToAll(ctx);
+ if(serr) {
+ goto errOut;
+ }
+
+ /* Initial cert verify state: verify with default system roots */
+ ctx->enableCertVerify = true;
+
+ /* snag root certs from Keychain, tolerate error */
+ addBuiltInCerts(ctx);
+
+ *contextPtr = ctx;
+ return noErr;
+
+errOut:
+ sslFree(ctx);
+ return serr;
+}
+
+
+/*
+ * Dispose of an SSLContext.
+ */
+OSStatus
+SSLDisposeContext (SSLContext *ctx)
+{
+ WaitingRecord *wait, *next;
+ SSLBuffer buf;
+
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ sslDeleteCertificateChain(ctx->localCert, ctx);
+ sslDeleteCertificateChain(ctx->encryptCert, ctx);
+ sslDeleteCertificateChain(ctx->peerCert, ctx);
+ ctx->localCert = ctx->encryptCert = ctx->peerCert = NULL;
+ SSLFreeBuffer(ctx->partialReadBuffer, ctx);
+
+ wait = ctx->recordWriteQueue;
+ while (wait)
+ { SSLFreeBuffer(wait->data, ctx);
+ next = wait->next;
+ buf.data = (uint8*)wait;
+ buf.length = sizeof(WaitingRecord);
+ SSLFreeBuffer(buf, ctx);
+ wait = next;
+ }
+
+ SSLFreeBuffer(ctx->dhPeerPublic, ctx);
+ SSLFreeBuffer(ctx->dhExchangePublic, ctx);
+ SSLFreeBuffer(ctx->dhPrivate, ctx);
+
+ CloseHash(SSLHashSHA1, ctx->shaState, ctx);
+ CloseHash(SSLHashMD5, ctx->md5State, ctx);
+
+ SSLFreeBuffer(ctx->sessionID, ctx);
+ SSLFreeBuffer(ctx->peerID, ctx);
+ SSLFreeBuffer(ctx->resumableSession, ctx);
+ SSLFreeBuffer(ctx->preMasterSecret, ctx);
+ SSLFreeBuffer(ctx->partialReadBuffer, ctx);
+ SSLFreeBuffer(ctx->fragmentedMessageCache, ctx);
+ SSLFreeBuffer(ctx->receivedDataBuffer, ctx);
+
+ if(ctx->peerDomainName) {
+ sslFree(ctx->peerDomainName);
+ ctx->peerDomainName = NULL;
+ ctx->peerDomainNameLen = 0;
+ }
+ SSLDisposeCipherSuite(&ctx->readCipher, ctx);
+ SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
+ SSLDisposeCipherSuite(&ctx->readPending, ctx);
+ SSLDisposeCipherSuite(&ctx->writePending, ctx);
+
+ sslFree(ctx->validCipherSpecs);
+ ctx->validCipherSpecs = NULL;
+ ctx->numValidCipherSpecs = 0;
+
+ /*
+ * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
+ * We really don't know what CSP the CL used to generate a public key (in fact,
+ * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
+ * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
+ * signingPubKey is not tecnically accurate. However, our public keys
+ * are all raw keys, and all Apple CSPs dispose of raw keys in the same
+ * way.
+ */
+ sslFreeKey(ctx->signingKeyCsp, &ctx->signingPubKey, NULL);
+ sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPubKey, NULL);
+ sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
+
+ sslFreeTrustedRoots(ctx);
+
+ detachFromAll(ctx);
+
+ memset(ctx, 0, sizeof(SSLContext));
+ sslFree(ctx);
+ sslCleanupSession();
+ return noErr;
+}
+
+/*
+ * Determine the state of an SSL session.
+ */
+OSStatus
+SSLGetSessionState (SSLContextRef context,
+ SSLSessionState *state) /* RETURNED */
+{
+ SSLSessionState rtnState = kSSLIdle;
+
+ if(context == NULL) {
+ return paramErr;
+ }
+ *state = rtnState;
+ switch(context->state) {
+ case SSL_HdskStateUninit:
+ case SSL_HdskStateServerUninit:
+ case SSL_HdskStateClientUninit:
+ rtnState = kSSLIdle;
+ break;
+ case SSL_HdskStateGracefulClose:
+ rtnState = kSSLClosed;
+ break;
+ case SSL_HdskStateErrorClose:
+ case SSL_HdskStateNoNotifyClose:
+ rtnState = kSSLAborted;
+ break;
+ case SSL2_HdskStateServerReady:
+ case SSL2_HdskStateClientReady:
+ rtnState = kSSLConnected;
+ break;
+ default:
+ assert((context->state >= SSL_HdskStateServerHello) &&
+ (context->state <= SSL2_HdskStateServerFinished));
+ rtnState = kSSLHandshake;
+ break;
+
+ }
+ *state = rtnState;
+ return noErr;
+}
+
+OSStatus
+SSLSetIOFuncs (SSLContextRef ctx,
+ SSLReadFunc read,
+ SSLWriteFunc write)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ ctx->ioCtx.read = read;
+ ctx->ioCtx.write = write;
+ return noErr;
+}
+
+OSStatus
+SSLSetConnection (SSLContextRef ctx,
+ SSLConnectionRef connection)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ ctx->ioCtx.ioRef = connection;
+ return noErr;
+}
+
+OSStatus
+SSLSetPeerDomainName (SSLContextRef ctx,
+ const char *peerName,
+ size_t peerNameLen)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+
+ /* free possible existing name */
+ if(ctx->peerDomainName) {
+ sslFree(ctx->peerDomainName);
+ }
+
+ /* copy in */
+ ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
+ if(ctx->peerDomainName == NULL) {
+ return memFullErr;
+ }
+ memmove(ctx->peerDomainName, peerName, peerNameLen);
+ ctx->peerDomainNameLen = peerNameLen;
+ return noErr;
+}
+
+/*
+ * Determine the buffer size needed for SSLGetPeerDomainName().
+ */
+OSStatus
+SSLGetPeerDomainNameLength (SSLContextRef ctx,
+ size_t *peerNameLen) // RETURNED
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *peerNameLen = ctx->peerDomainNameLen;
+ return noErr;
+}
+
+OSStatus
+SSLGetPeerDomainName (SSLContextRef ctx,
+ char *peerName, // returned here
+ size_t *peerNameLen) // IN/OUT
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(*peerNameLen < ctx->peerDomainNameLen) {
+ return errSSLBufferOverflow;
+ }
+ memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
+ *peerNameLen = ctx->peerDomainNameLen;
+ return noErr;
+}
+
+OSStatus
+SSLSetProtocolVersion (SSLContextRef ctx,
+ SSLProtocol version)
+{
+ SSLProtocolVersion versInt;
+ SSLProtocolVersion versMax;
+
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+
+ /* convert external representation to private */
+ switch(version) {
+ case kSSLProtocolUnknown:
+ versInt = SSL_Version_Undetermined;
+ versMax = DEFAULT_MAX_VERSION;
+ break;
+ case kSSLProtocol2:
+ versInt = versMax = SSL_Version_2_0;
+ break;
+ case kSSLProtocol3:
+ /* this tells us to do our best but allows 2.0 */
+ versInt = SSL_Version_Undetermined;
+ versMax = SSL_Version_3_0;
+ break;
+ case kSSLProtocol3Only:
+ versInt = SSL_Version_3_0_Only;
+ versMax = SSL_Version_3_0;
+ break;
+ case kTLSProtocol1:
+ /* this tells us to do our best but allows 2.0 */
+ versInt = SSL_Version_Undetermined;
+ versMax = TLS_Version_1_0;
+ break;
+ case kTLSProtocol1Only:
+ versInt = TLS_Version_1_0_Only;
+ versMax = TLS_Version_1_0;
+ break;
+ default:
+ return paramErr;
+ }
+ ctx->reqProtocolVersion = ctx->negProtocolVersion = versInt;
+ ctx->maxProtocolVersion = versMax;
+ return noErr;
+}
+
+static SSLProtocol convertProtToExtern(SSLProtocolVersion prot)
+{
+ switch(prot) {
+ case SSL_Version_Undetermined:
+ return kSSLProtocolUnknown;
+ case SSL_Version_3_0_Only:
+ return kSSLProtocol3Only;
+ case SSL_Version_2_0:
+ return kSSLProtocol2;
+ case SSL_Version_3_0:
+ return kSSLProtocol3;
+ case TLS_Version_1_0_Only:
+ return kTLSProtocol1Only;
+ case TLS_Version_1_0:
+ return kTLSProtocol1;
+ /* this can happen in an intermediate state while negotiation
+ * is active...right? */
+ case SSL_Version_3_0_With_2_0_Hello:
+ return kSSLProtocolUnknown;
+ default:
+ sslErrorLog("convertProtToExtern: bad prot\n");
+ return kSSLProtocolUnknown;
+ }
+ /* not reached but make compiler happy */
+ return kSSLProtocolUnknown;
+}
+
+OSStatus
+SSLGetProtocolVersion (SSLContextRef ctx,
+ SSLProtocol *protocol) /* RETURNED */
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *protocol = convertProtToExtern(ctx->reqProtocolVersion);
+ return noErr;
+}
+
+OSStatus
+SSLGetNegotiatedProtocolVersion (SSLContextRef ctx,
+ SSLProtocol *protocol) /* RETURNED */
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *protocol = convertProtToExtern(ctx->negProtocolVersion);
+ return noErr;
+}
+
+OSStatus
+SSLSetEnableCertVerify (SSLContextRef ctx,
+ Boolean enableVerify)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ ctx->enableCertVerify = enableVerify;
+ return noErr;
+}
+
+OSStatus
+SSLGetEnableCertVerify (SSLContextRef ctx,
+ Boolean *enableVerify)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *enableVerify = ctx->enableCertVerify;
+ return noErr;
+}
+
+OSStatus
+SSLSetAllowsExpiredCerts(SSLContextRef ctx,
+ Boolean allowExpired)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ ctx->allowExpiredCerts = allowExpired;
+ return noErr;
+}
+
+OSStatus
+SSLGetAllowsExpiredCerts (SSLContextRef ctx,
+ Boolean *allowExpired)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *allowExpired = ctx->allowExpiredCerts;
+ return noErr;
+}
+
+OSStatus
+SSLSetAllowsExpiredRoots(SSLContextRef ctx,
+ Boolean allowExpired)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ ctx->allowExpiredRoots = allowExpired;
+ return noErr;
+}
+
+OSStatus
+SSLGetAllowsExpiredRoots (SSLContextRef ctx,
+ Boolean *allowExpired)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *allowExpired = ctx->allowExpiredRoots;
+ return noErr;
+}
+
+OSStatus SSLSetAllowsAnyRoot(
+ SSLContextRef ctx,
+ Boolean anyRoot)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ ctx->allowAnyRoot = anyRoot;
+ return noErr;
+}
+
+OSStatus
+SSLGetAllowsAnyRoot(
+ SSLContextRef ctx,
+ Boolean *anyRoot)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *anyRoot = ctx->allowAnyRoot;
+ return noErr;
+}
+
+OSStatus
+SSLSetTrustedRoots (SSLContextRef ctx,
+ CFArrayRef trustedRoots,
+ Boolean replaceExisting)
+{
+ unsigned dex;
+ unsigned outDex;
+ unsigned numIncoming;
+ uint32 numCerts;
+ CSSM_DATA_PTR newRoots = NULL;
+ const CSSM_DATA *existAnchors = NULL;
+ uint32 numExistAnchors = 0;
+ OSStatus ortn = noErr;
+
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ numCerts = numIncoming = CFArrayGetCount(trustedRoots);
+ if(!replaceExisting) {
+ if(ctx->trustedCerts != NULL) {
+ /* adding to existing store */
+ existAnchors = ctx->trustedCerts;
+ numExistAnchors = ctx->numTrustedCerts;
+ }
+ else {
+ /* adding to system roots */
+ ortn = SecTrustGetCSSMAnchorCertificates(&existAnchors,
+ &numExistAnchors);
+ if(ortn) {
+ /* should never happen */
+ return ortn;
+ }
+ }
+ numCerts += numExistAnchors;
+ }
+ newRoots = (CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA));
+ memset(newRoots, 0, numCerts * sizeof(CSSM_DATA));
+
+ /* Caller's certs first */
+ for(dex=0, outDex=0; dex<numIncoming; dex++, outDex++) {
+ CSSM_DATA certData;
+ SecCertificateRef secCert = (SecCertificateRef)
+ CFArrayGetValueAtIndex(trustedRoots, dex);
+
+ if(CFGetTypeID(secCert) != SecCertificateGetTypeID()) {
+ /* elements of trustedRoots must be SecCertificateRefs */
+ ortn = paramErr;
+ goto abort;
+ }
+ ortn = SecCertificateGetData(secCert, &certData);
+ if(ortn) {
+ goto abort;
+ }
+ stSetUpCssmData(&newRoots[outDex], certData.Length);
+ memmove(newRoots[outDex].Data, certData.Data, certData.Length);
+ }
+
+ /* now existing roots - either ours, or the system's */
+ for(dex=0; dex<numExistAnchors; dex++, outDex++) {
+ stSetUpCssmData(&newRoots[outDex], existAnchors[dex].Length);
+ memmove(newRoots[outDex].Data, existAnchors[dex].Data,
+ existAnchors[dex].Length);
+ }
+
+ /* success - replace context values */
+ sslFreeTrustedRoots(ctx);
+ ctx->numTrustedCerts = numCerts;
+ ctx->trustedCerts = newRoots;
+ return noErr;
+
+abort:
+ sslFree(newRoots);
+ return ortn;
+}
+
+OSStatus
+SSLGetTrustedRoots (SSLContextRef ctx,
+ CFArrayRef *trustedRoots) /* RETURNED */
+{
+ uint32 numCerts;
+ const CSSM_DATA *certs;
+ CFMutableArrayRef certArray;
+ unsigned dex;
+ SecCertificateRef secCert;
+ OSStatus ortn;
+
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(ctx->trustedCerts != NULL) {
+ /* use ours */
+ certs = ctx->trustedCerts;
+ numCerts = ctx->numTrustedCerts;
+ }
+ else {
+ /* use default system roots */
+ OSStatus ortn = SecTrustGetCSSMAnchorCertificates(&certs,
+ &numCerts);
+ if(ortn) {
+ /* should never happen */
+ return ortn;
+ }
+ }
+
+ certArray = CFArrayCreateMutable(kCFAllocatorDefault,
+ (CFIndex)numCerts, &kCFTypeArrayCallBacks);
+ if(certArray == NULL) {
+ return memFullErr;
+ }
+ for(dex=0; dex<numCerts; dex++) {
+ ortn = SecCertificateCreateFromData(&certs[dex],
+ CSSM_CERT_X_509v3,
+ CSSM_CERT_ENCODING_DER,
+ &secCert);
+ if(ortn) {
+ CFRelease(certArray);
+ return ortn;
+ }
+ CFArrayAppendValue(certArray, secCert);
+ }
+ *trustedRoots = certArray;
+ return noErr;
+}
+
+OSStatus
+SSLSetClientSideAuthenticate (SSLContext *ctx,
+ SSLAuthenticate auth)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ ctx->clientAuth = auth;
+ switch(auth) {
+ case kNeverAuthenticate:
+ ctx->tryClientAuth = false;
+ break;
+ case kAlwaysAuthenticate:
+ case kTryAuthenticate:
+ ctx->tryClientAuth = true;
+ break;
+ }
+ return noErr;
+}
+
+OSStatus
+SSLGetClientCertificateState (SSLContextRef ctx,
+ SSLClientCertificateState *clientState)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *clientState = ctx->clientCertState;
+ return noErr;
+}
+
+OSStatus
+SSLSetCertificate (SSLContextRef ctx,
+ CFArrayRef certRefs)
+{
+ /*
+ * -- free localCerts if we have any
+ * -- Get raw cert data, convert to ctx->localCert
+ * -- get pub, priv keys from certRef[0]
+ * -- validate cert chain
+ */
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ return parseIncomingCerts(ctx,
+ certRefs,
+ &ctx->localCert,
+ &ctx->signingPubKey,
+ &ctx->signingPrivKey,
+ &ctx->signingKeyCsp
+ #if ST_KC_KEYS_NEED_REF
+ ,
+ &ctx->signingKeyRef
+ #else
+ );
+ #endif
+}
+
+OSStatus
+SSLSetEncryptionCertificate (SSLContextRef ctx,
+ CFArrayRef certRefs)
+{
+ /*
+ * -- free encryptCert if we have any
+ * -- Get raw cert data, convert to ctx->encryptCert
+ * -- get pub, priv keys from certRef[0]
+ * -- validate cert chain
+ */
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ return parseIncomingCerts(ctx,
+ certRefs,
+ &ctx->encryptCert,
+ &ctx->encryptPubKey,
+ &ctx->encryptPrivKey,
+ &ctx->encryptKeyCsp
+ #if ST_KC_KEYS_NEED_REF
+ ,
+ &ctx->encryptKeyRef);
+ #else
+ );
+ #endif
+}
+
+#if ST_MANAGES_TRUSTED_ROOTS
+
+/*
+ * Add (optional, additional) trusted root certs.
+ */
+OSStatus
+SSLSetTrustedRootCertKC (SSLContextRef ctx,
+ KCRef keyChainRef,
+ Boolean deleteExisting)
+{
+ /*
+ * -- free trustedCerts if deleteExisting
+ * -- Get raw cert data, add to ctx->trustedCerts
+ * -- verify that each of these is a valid (self-verifying)
+ * root cert
+ * -- add each subject name to acceptableDNList
+ */
+ if((ctx == NULL) || (keyChainRef == nil)) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ if(deleteExisting) {
+ sslFreeTrustedRoots(ctx);
+ }
+ return parseTrustedKeychain(ctx, keyChainRef);
+}
+
+OSStatus
+SSLSetNewRootKC (SSLContextRef ctx,
+ KCRef keyChainRef,
+ void *accessCreds)
+{
+ if((ctx == NULL) || (keyChainRef == nil)) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ if(ctx->newRootCertKc != NULL) {
+ /* can't do this multiple times */
+ return badReqErr;
+ }
+ ctx->newRootCertKc = keyChainRef;
+ ctx->accessCreds = accessCreds;
+ return noErr;
+}
+#endif /* ST_MANAGES_TRUSTED_ROOTS */
+
+OSStatus
+SSLSetPeerID (SSLContext *ctx,
+ const void *peerID,
+ size_t peerIDLen)
+{
+ OSStatus serr;
+
+ /* copy peerId to context->peerId */
+ if((ctx == NULL) ||
+ (peerID == NULL) ||
+ (peerIDLen == 0)) {
+ return paramErr;
+ }
+ if(sslIsSessionActive(ctx)) {
+ /* can't do this with an active session */
+ return badReqErr;
+ }
+ SSLFreeBuffer(ctx->peerID, ctx);
+ serr = SSLAllocBuffer(ctx->peerID, peerIDLen, ctx);
+ if(serr) {
+ return serr;
+ }
+ memmove(ctx->peerID.data, peerID, peerIDLen);
+ return noErr;
+}
+
+OSStatus
+SSLGetPeerID (SSLContextRef ctx,
+ const void **peerID,
+ size_t *peerIDLen)
+{
+ *peerID = ctx->peerID.data; // may be NULL
+ *peerIDLen = ctx->peerID.length;
+ return noErr;
+}
+
+OSStatus
+SSLGetNegotiatedCipher (SSLContextRef ctx,
+ SSLCipherSuite *cipherSuite)
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(!sslIsSessionActive(ctx)) {
+ return badReqErr;
+ }
+ *cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
+ return noErr;
+}
+
+/*
+ * Add an acceptable distinguished name (client authentication only).
+ */
+OSStatus
+SSLAddDistinguishedName(
+ SSLContextRef ctx,
+ const void *derDN,
+ size_t derDNLen)
+{
+ DNListElem *dn;
+ OSStatus err;
+
+ dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
+ if(dn == NULL) {
+ return memFullErr;
+ }
+ if ((err = SSLAllocBuffer(dn->derDN, derDNLen, ctx)) != 0)
+ return err;
+ memcpy(dn->derDN.data, derDN, derDNLen);
+ dn->next = ctx->acceptableDNList;
+ ctx->acceptableDNList = dn;
+ return noErr;
+}
+
+/*
+ * Request peer certificates. Valid anytime, subsequent to
+ * a handshake attempt.
+ */
+OSStatus
+SSLGetPeerCertificates (SSLContextRef ctx,
+ CFArrayRef *certs)
+{
+ uint32 numCerts;
+ CFMutableArrayRef ca;
+ CFIndex i;
+ SecCertificateRef cfd;
+ OSStatus ortn;
+ CSSM_DATA certData;
+ SSLCertificate *scert;
+
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ *certs = NULL;
+
+ /*
+ * Copy peerCert, a chain of SSLCertificates, to a CFArray of
+ * CFDataRefs, each of which is one DER-encoded cert.
+ */
+ numCerts = SSLGetCertificateChainLength(ctx->peerCert);
+ if(numCerts == 0) {
+ return noErr;
+ }
+ ca = CFArrayCreateMutable(kCFAllocatorDefault,
+ (CFIndex)numCerts, &kCFTypeArrayCallBacks);
+ if(ca == NULL) {
+ return memFullErr;
+ }
+
+ /*
+ * Caller gets leaf cert first, the opposite of the way we store them.
+ */
+ scert = ctx->peerCert;
+ for(i=0; (unsigned)i<numCerts; i++) {
+ assert(scert != NULL); /* else SSLGetCertificateChainLength
+ * broken */
+ SSLBUF_TO_CSSM(&scert->derCert, &certData);
+ ortn = SecCertificateCreateFromData(&certData,
+ CSSM_CERT_X_509v3,
+ CSSM_CERT_ENCODING_DER,
+ &cfd);
+ if(ortn) {
+ CFRelease(ca);
+ return ortn;
+ }
+ /* insert at head of array */
+ CFArrayInsertValueAtIndex(ca, 0, cfd);
+ scert = scert->next;
+ }
+ *certs = ca;
+ return noErr;
+}
+
+OSStatus SSLInternalMasterSecret(
+ SSLContextRef ctx,
+ void *secret, // mallocd by caller, SSL_MASTER_SECRET_SIZE
+ size_t *secretSize) // in/out
+{
+ if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
+ return paramErr;
+ }
+ if(*secretSize < SSL_MASTER_SECRET_SIZE) {
+ return paramErr;
+ }
+ memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
+ *secretSize = SSL_MASTER_SECRET_SIZE;
+ return noErr;
+}
+
+OSStatus SSLInternalServerRandom(
+ SSLContextRef ctx,
+ void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
+ size_t *randSize) // in/out
+{
+ if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
+ return paramErr;
+ }
+ if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
+ return paramErr;
+ }
+ memmove(rand, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
+ *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
+ return noErr;
+}
+
+OSStatus SSLInternalClientRandom(
+ SSLContextRef ctx,
+ void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
+ size_t *randSize) // in/out
+{
+ if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
+ return paramErr;
+ }
+ if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
+ return paramErr;
+ }
+ memmove(rand, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
+ *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
+ return noErr;
+}
+
+
+
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslDebug.c
-
- Contains: Debugging support.
-
- Written by: Doug Mitchell
-
- Copyright: (c) 1998 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- 03/10/98 dpm Created.
-
-*/
-
-
-#include "sslDebug.h"
-
-#if SSL_DEBUG && macintosh
-
-#include <string.h>
-#include <Types.h>
-#include <TextUtils.h>
-
-/* common log macros */
-
-/* this one needs a writable string */
-static void logCom(unsigned char *str) {
- c2pstr((char *)str);
- DebugStr(str);
-}
-
-/* remaining ones can take constant strings */
-void dblog0(char *str) {
- Str255 outStr;
- strcpy((char *)outStr, str);
- logCom(outStr);
-}
-
-void dblog1(char *str, void *arg1) {
- Str255 outStr;
- sprintf((char *)outStr, str, arg1);
- logCom(outStr);
-}
-
-void dblog2(char *str, void * arg1, void * arg2) {
- Str255 outStr;
- sprintf((char *)outStr, str, arg1, arg2);
- logCom(outStr);
-}
-
-void dblog3(char *str, void * arg1, void * arg2, void * arg3) {
- Str255 outStr;
- sprintf((char *)outStr, str, arg1, arg2, arg3);
- logCom(outStr);
-}
-
-void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4) {
- Str255 outStr;
- sprintf((char *)outStr, str, arg1, arg2, arg3, arg4);
- logCom(outStr);
-}
-
-#endif /* SSL_DEBUG */
-
-/*
- * Panic/exit.
- */
-#include <stdlib.h>
-volatile void sslPanic(const char *reason)
-{
- errorLog0((char *)reason);
- /* FIXME */
- exit(1);
-}
-
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslDigests.cpp
+
+ Contains: interface between SSL and SHA, MD5 digest implementations
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "cryptType.h"
+#include "sslMemory.h"
+#include "sslDigests.h"
+#include "sslDebug.h"
+#include "appleCdsa.h"
+#include <Security/cssm.h>
+#include <string.h>
+
+#define DIGEST_PRINT 0
+#if DIGEST_PRINT
+#define dgprintf(s) printf s
+#else
+#define dgprintf(s)
+#endif
+
+/*
+ * Common digest context. The SSLBuffer.data pointer in a "digest state" argument
+ * casts to one of these.
+ */
+typedef struct {
+ CSSM_CC_HANDLE hashHand;
+} cdsaHashContext;
+
+const UInt8 SSLMACPad1[MAX_MAC_PADDING] =
+{
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36
+};
+
+const UInt8 SSLMACPad2[MAX_MAC_PADDING] =
+{
+ 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+ 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+ 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+ 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+ 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+ 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C
+};
+
+/*
+ * Public general hash functions
+ */
+
+/*
+ * A convenience wrapper for HashReference.clone, which has the added benefit of
+ * allocating the state buffer for the caller.
+ */
+OSStatus
+CloneHashState(
+ const HashReference &ref,
+ const SSLBuffer &state,
+ SSLBuffer &newState,
+ SSLContext *ctx)
+{
+ OSStatus err;
+ if ((err = SSLAllocBuffer(newState, ref.contextSize, ctx)) != 0)
+ return err;
+ return ref.clone(state, newState);
+}
+
+/*
+ * Wrapper for HashReference.init.
+ */
+OSStatus
+ReadyHash(const HashReference &ref, SSLBuffer &state, SSLContext *ctx)
+{
+ OSStatus err;
+ if ((err = SSLAllocBuffer(state, ref.contextSize, ctx)) != 0)
+ return err;
+ return ref.init(state, ctx);
+}
+
+/*
+ * Wrapper for HashReference.clone. Tolerates NULL digestCtx and frees it if it's
+ * there.
+ */
+OSStatus CloseHash(const HashReference &ref, SSLBuffer &state, SSLContext *ctx)
+{
+ OSStatus serr;
+
+ if(state.data == NULL) {
+ return noErr;
+ }
+ serr = ref.close(state, ctx);
+ if(serr) {
+ return serr;
+ }
+ return SSLFreeBuffer(state, ctx);
+}
+
+static OSStatus HashNullInit(SSLBuffer &digestCtx, SSLContext *sslCtx);
+static OSStatus HashNullUpdate(SSLBuffer &digestCtx, const SSLBuffer &data);
+static OSStatus HashNullFinal(SSLBuffer &digestCtx, SSLBuffer &digest);
+static OSStatus HashNullClose(SSLBuffer &digestCtx, SSLContext *sslCtx);
+static OSStatus HashNullClone(const SSLBuffer &src, SSLBuffer &dst);
+
+static OSStatus HashMD5Init(SSLBuffer &digestCtx, SSLContext *sslCtx);
+static OSStatus HashSHA1Init(SSLBuffer &digestCtx, SSLContext *sslCtx);
+static OSStatus cdsaHashInit(SSLBuffer &digestCtx, SSLContext *sslCtx,
+ CSSM_ALGORITHMS digestAlg);
+static OSStatus cdsaHashUpdate(SSLBuffer &digestCtx, const SSLBuffer &data);
+static OSStatus cdsaHashFinal(SSLBuffer &digestCtx, SSLBuffer &digest);
+static OSStatus cdsaHashClose(SSLBuffer &digestCtx, SSLContext *sslCtx);
+static OSStatus cdsaHashClone(const SSLBuffer &src, SSLBuffer &dest);
+
+/*
+ * These are the handles by which the bulk of digesting work
+ * is done.
+ */
+const HashReference SSLHashNull =
+ {
+ 0,
+ 0,
+ 0,
+ HashNullInit,
+ HashNullUpdate,
+ HashNullFinal,
+ HashNullClose,
+ HashNullClone
+ };
+
+const HashReference SSLHashMD5 =
+ {
+ sizeof(cdsaHashContext),
+ 16,
+ 48,
+ HashMD5Init,
+ cdsaHashUpdate,
+ cdsaHashFinal,
+ cdsaHashClose,
+ cdsaHashClone
+ };
+
+const HashReference SSLHashSHA1 =
+ {
+ sizeof(cdsaHashContext),
+ 20,
+ 40,
+ HashSHA1Init,
+ cdsaHashUpdate,
+ cdsaHashFinal,
+ cdsaHashClose,
+ cdsaHashClone
+ };
+
+/*** NULL ***/
+static OSStatus HashNullInit(SSLBuffer &digestCtx, SSLContext *sslCtx) {
+ return noErr;
+}
+
+static OSStatus HashNullUpdate(SSLBuffer &digestCtx, const SSLBuffer &data) {
+ return noErr;
+}
+
+static OSStatus HashNullFinal(SSLBuffer &digestCtx, SSLBuffer &digest) {
+ return noErr;
+}
+static OSStatus HashNullClose(SSLBuffer &digestCtx, SSLContext *sslCtx) {
+ return noErr;
+}
+static OSStatus HashNullClone(const SSLBuffer &src, SSLBuffer &dest) {
+ return noErr;
+}
+
+static OSStatus HashMD5Init(SSLBuffer &digestCtx, SSLContext *sslCtx)
+{
+ assert(digestCtx.length >= sizeof(cdsaHashContext));
+ return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_MD5);
+}
+
+static OSStatus HashSHA1Init(SSLBuffer &digestCtx, SSLContext *sslCtx)
+{
+ assert(digestCtx.length >= sizeof(cdsaHashContext));
+ return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_SHA1);
+}
+
+/* common digest functions via CDSA */
+static OSStatus cdsaHashInit(SSLBuffer &digestCtx,
+ SSLContext *sslCtx,
+ CSSM_ALGORITHMS digestAlg)
+{
+ OSStatus serr;
+ cdsaHashContext *cdsaCtx;
+ CSSM_CC_HANDLE hashHand = 0;
+ CSSM_RETURN crtn;
+
+ assert(digestCtx.length >= sizeof(cdsaHashContext));
+ serr = attachToCsp(sslCtx); // should be a nop
+ if(serr) {
+ return serr;
+ }
+ cdsaCtx = (cdsaHashContext *)digestCtx.data;
+ cdsaCtx->hashHand = 0;
+ dgprintf(("###cdsaHashInit cdsaCtx %p\n", cdsaCtx));
+
+ /* cook up a digest context, initialize it */
+ crtn = CSSM_CSP_CreateDigestContext(sslCtx->cspHand,
+ digestAlg,
+ &hashHand);
+ if(crtn) {
+ sslErrorLog("CSSM_CSP_CreateDigestContext failure\n");
+ return errSSLCrypto;
+ }
+ crtn = CSSM_DigestDataInit(hashHand);
+ if(crtn) {
+ CSSM_DeleteContext(hashHand);
+ sslErrorLog("CSSM_DigestDataInit failure\n");
+ return errSSLCrypto;
+ }
+ cdsaCtx->hashHand = hashHand;
+ return noErr;
+}
+
+static OSStatus cdsaHashUpdate(SSLBuffer &digestCtx, const SSLBuffer &data)
+{
+ cdsaHashContext *cdsaCtx;
+ CSSM_RETURN crtn;
+ CSSM_DATA cdata;
+
+ assert(digestCtx.length >= sizeof(cdsaHashContext));
+ cdsaCtx = (cdsaHashContext *)digestCtx.data;
+ //dgprintf(("###cdsaHashUpdate cdsaCtx %p\n", cdsaCtx));
+
+ SSLBUF_TO_CSSM(&data, &cdata);
+ crtn = CSSM_DigestDataUpdate(cdsaCtx->hashHand, &cdata, 1);
+ if(crtn) {
+ sslErrorLog("CSSM_DigestDataUpdate failure\n");
+ return errSSLCrypto;
+ }
+ else {
+ return noErr;
+ }
+}
+
+static OSStatus cdsaHashFinal(SSLBuffer &digestCtx, SSLBuffer &digest)
+{
+ cdsaHashContext *cdsaCtx;
+ CSSM_RETURN crtn;
+ CSSM_DATA cdata;
+ OSStatus srtn = noErr;
+
+ assert(digestCtx.length >= sizeof(cdsaHashContext));
+ cdsaCtx = (cdsaHashContext *)digestCtx.data;
+ dgprintf(("###cdsaHashFinal cdsaCtx %p\n", cdsaCtx));
+ SSLBUF_TO_CSSM(&digest, &cdata);
+ crtn = CSSM_DigestDataFinal(cdsaCtx->hashHand, &cdata);
+ if(crtn) {
+ sslErrorLog("CSSM_DigestDataFinal failure\n");
+ srtn = errSSLCrypto;
+ }
+ else {
+ digest.length = cdata.Length;
+ }
+ CSSM_DeleteContext(cdsaCtx->hashHand);
+ cdsaCtx->hashHand = 0;
+ return srtn;
+}
+
+static OSStatus cdsaHashClose(SSLBuffer &digestCtx, SSLContext *sslCtx)
+{
+ cdsaHashContext *cdsaCtx;
+
+ assert(digestCtx.length >= sizeof(cdsaHashContext));
+ cdsaCtx = (cdsaHashContext *)digestCtx.data;
+ dgprintf(("###cdsaHashClose cdsaCtx %p\n", cdsaCtx));
+ if(cdsaCtx->hashHand != 0) {
+ CSSM_DeleteContext(cdsaCtx->hashHand);
+ cdsaCtx->hashHand = 0;
+ }
+ return noErr;
+}
+
+static OSStatus cdsaHashClone(const SSLBuffer &src, SSLBuffer &dst)
+{
+ cdsaHashContext *srcCtx;
+ cdsaHashContext *dstCtx;
+ CSSM_RETURN crtn;
+
+ assert(src.length >= sizeof(cdsaHashContext));
+ assert(dst.length >= sizeof(cdsaHashContext));
+ srcCtx = (cdsaHashContext *)src.data;
+ dstCtx = (cdsaHashContext *)dst.data;
+ dgprintf(("###cdsaHashClone srcCtx %p dstCtx %p\n", srcCtx, dstCtx));
+
+ crtn = CSSM_DigestDataClone(srcCtx->hashHand, &dstCtx->hashHand);
+ if(crtn) {
+ sslErrorLog("CSSM_DigestDataClone failure\n");
+ return errSSLCrypto;
+ }
+ else {
+ return noErr;
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslHandshake.cpp
+
+ Contains: SSL 3.0 handshake state machine.
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslMemory.h"
+#include "sslAlertMessage.h"
+#include "sslSession.h"
+#include "sslUtils.h"
+#include "sslDebug.h"
+#include "appleCdsa.h"
+#include "sslDigests.h"
+
+#include <string.h>
+#include <assert.h>
+
+#define REQUEST_CERT_CORRECT 0
+
+static OSStatus SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
+
+OSStatus
+SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
+{ OSStatus err;
+ sint32 remaining;
+ UInt8 *p;
+ SSLHandshakeMsg message;
+ SSLBuffer messageData;
+
+ if (ctx->fragmentedMessageCache.data != 0)
+ { if ((err = SSLReallocBuffer(ctx->fragmentedMessageCache,
+ ctx->fragmentedMessageCache.length + rec.contents.length,
+ ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ memcpy(ctx->fragmentedMessageCache.data + ctx->fragmentedMessageCache.length,
+ rec.contents.data, rec.contents.length);
+ remaining = ctx->fragmentedMessageCache.length;
+ p = ctx->fragmentedMessageCache.data;
+ }
+ else
+ { remaining = rec.contents.length;
+ p = rec.contents.data;
+ }
+
+ while (remaining > 0)
+ { if (remaining < 4)
+ break; /* we must have at least a header */
+
+ messageData.data = p;
+ message.type = (SSLHandshakeType)*p++;
+ message.contents.length = SSLDecodeInt(p, 3);
+ if (((int)(message.contents.length + 4)) > remaining)
+ break;
+
+ p += 3;
+ message.contents.data = p;
+ p += message.contents.length;
+ messageData.length = 4 + message.contents.length;
+ assert(p == messageData.data + messageData.length);
+
+ /* message fragmentation */
+ remaining -= messageData.length;
+ if ((err = SSLProcessHandshakeMessage(message, ctx)) != 0)
+ return err;
+
+ if (message.type != SSL_HdskHelloRequest)
+ { if ((err = SSLHashSHA1.update(ctx->shaState, messageData)) != 0 ||
+ (err = SSLHashMD5.update(ctx->md5State, messageData)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+
+ if ((err = SSLAdvanceHandshake(message.type, ctx)) != 0)
+ return err;
+ }
+
+ if (remaining > 0) /* Fragmented handshake message */
+ { /* If there isn't a cache, allocate one */
+ if (ctx->fragmentedMessageCache.data == 0)
+ { if ((err = SSLAllocBuffer(ctx->fragmentedMessageCache, remaining, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+ if (p != ctx->fragmentedMessageCache.data)
+ { memcpy(ctx->fragmentedMessageCache.data, p, remaining);
+ ctx->fragmentedMessageCache.length = remaining;
+ }
+ }
+ else if (ctx->fragmentedMessageCache.data != 0)
+ { if ((err = SSLFreeBuffer(ctx->fragmentedMessageCache, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+
+ return noErr;
+}
+
+static OSStatus
+SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
+{ OSStatus err;
+
+ err = noErr;
+ SSLLogHdskMsg(message.type, 0);
+ switch (message.type)
+ { case SSL_HdskHelloRequest:
+ if (ctx->protocolSide != SSL_ClientSide)
+ goto wrongMessage;
+ if (message.contents.length > 0)
+ err = errSSLProtocol;
+ break;
+ case SSL_HdskClientHello:
+ if (ctx->state != SSL_HdskStateServerUninit)
+ goto wrongMessage;
+ err = SSLProcessClientHello(message.contents, ctx);
+ break;
+ case SSL_HdskServerHello:
+ if (ctx->state != SSL_HdskStateServerHello &&
+ ctx->state != SSL_HdskStateServerHelloUnknownVersion)
+ goto wrongMessage;
+ err = SSLProcessServerHello(message.contents, ctx);
+ break;
+ case SSL_HdskCert:
+ if (ctx->state != SSL_HdskStateCert &&
+ ctx->state != SSL_HdskStateClientCert)
+ goto wrongMessage;
+ err = SSLProcessCertificate(message.contents, ctx);
+ if(ctx->protocolSide == SSL_ServerSide) {
+ if(err) {
+ ctx->clientCertState = kSSLClientCertRejected;
+ }
+ else if(ctx->peerCert != NULL) {
+ /*
+ * This still might change if cert verify msg
+ * fails. Note we avoid going to state
+ * if we get en empty cert message which is
+ * otherwise valid.
+ */
+ ctx->clientCertState = kSSLClientCertSent;
+ }
+ }
+ break;
+ case SSL_HdskCertRequest:
+ if (((ctx->state != SSL_HdskStateHelloDone) &&
+ (ctx->state != SSL_HdskStateKeyExchange))
+ || ctx->certRequested)
+ goto wrongMessage;
+ err = SSLProcessCertificateRequest(message.contents, ctx);
+ break;
+ case SSL_HdskServerKeyExchange:
+ /*
+ * Since this message is optional, and completely at the
+ * server's discretion, we need to be able to handle this
+ * in one of two states...
+ */
+ switch(ctx->state) {
+ case SSL_HdskStateKeyExchange: /* explicitly waiting for this */
+ case SSL_HdskStateHelloDone:
+ break;
+ default:
+ goto wrongMessage;
+ }
+ err = SSLProcessServerKeyExchange(message.contents, ctx);
+ break;
+ case SSL_HdskServerHelloDone:
+ if (ctx->state != SSL_HdskStateHelloDone)
+ goto wrongMessage;
+ err = SSLProcessServerHelloDone(message.contents, ctx);
+ break;
+ case SSL_HdskCertVerify:
+ if (ctx->state != SSL_HdskStateClientCertVerify)
+ goto wrongMessage;
+ err = SSLProcessCertificateVerify(message.contents, ctx);
+ assert(ctx->protocolSide == SSL_ServerSide);
+ if(err) {
+ ctx->clientCertState = kSSLClientCertRejected;
+ }
+ break;
+ case SSL_HdskClientKeyExchange:
+ if (ctx->state != SSL_HdskStateClientKeyExchange)
+ goto wrongMessage;
+ err = SSLProcessKeyExchange(message.contents, ctx);
+ break;
+ case SSL_HdskFinished:
+ if (ctx->state != SSL_HdskStateFinished)
+ goto wrongMessage;
+ err = SSLProcessFinished(message.contents, ctx);
+ break;
+ default:
+ goto wrongMessage;
+ break;
+ }
+
+ if (err)
+ { if (err == errSSLProtocol)
+ SSLFatalSessionAlert(SSL_AlertIllegalParam, ctx);
+ else if (err == errSSLNegotiation)
+ SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
+ else
+ SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ }
+ return err;
+
+wrongMessage:
+ SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ return errSSLProtocol;
+}
+
+OSStatus
+SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer sessionIdentifier;
+
+ switch (processed)
+ { case SSL_HdskHelloRequest:
+ /*
+ * Reset the client auth state machine in case this is
+ * a renegotiation.
+ */
+ ctx->certRequested = 0;
+ ctx->certSent = 0;
+ ctx->certReceived = 0;
+ ctx->x509Requested = 0;
+ ctx->clientCertState = kSSLClientCertNone;
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
+ return err;
+ SSLChangeHdskState(ctx, SSL_HdskStateServerHello);
+ break;
+ case SSL_HdskClientHello:
+ assert(ctx->protocolSide == SSL_ServerSide);
+ if (ctx->sessionID.data != 0)
+ /* If session ID != 0, client is trying to resume */
+ { if (ctx->resumableSession.data != 0)
+ { if ((err = SSLRetrieveSessionID(ctx->resumableSession,
+ &sessionIdentifier, ctx)) != 0)
+ return err;
+ if (sessionIdentifier.length == ctx->sessionID.length &&
+ memcmp(sessionIdentifier.data, ctx->sessionID.data,
+ ctx->sessionID.length) == 0)
+ { /* Everything matches; resume the session */
+ sslLogResumSessDebug("===RESUMING SSL3 server-side session");
+ if ((err = SSLInstallSessionFromData(ctx->resumableSession,
+ ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello,
+ ctx)) != 0)
+ return err;
+ if ((err = SSLInitPendingCiphers(ctx)) != 0 ||
+ (err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ if ((err =
+ SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
+ ctx)) != 0)
+ return err;
+ /* Install new cipher spec on write side */
+ if ((err = SSLDisposeCipherSuite(&ctx->writeCipher,
+ ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ ctx->writeCipher = ctx->writePending;
+ ctx->writeCipher.ready = 0;
+ /* Can't send data until Finished is sent */
+ memset(&ctx->writePending, 0, sizeof(CipherContext));
+ /* Zero out old data */
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
+ ctx)) != 0)
+ return err;
+ /* Finished has been sent; enable data t6ransfer on
+ * write channel */
+ ctx->writeCipher.ready = 1;
+ SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
+ break;
+ }
+ else {
+ sslLogResumSessDebug(
+ "===FAILED TO RESUME SSL3 server-side session");
+ }
+ if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0 ||
+ (err = SSLDeleteSessionData(ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+ if ((err = SSLFreeBuffer(ctx->sessionID, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+
+ /*
+ * If we get here, we're not resuming; generate a new session ID
+ * if we know our peer
+ */
+ if (ctx->peerID.data != 0)
+ { /* Ignore errors; just treat as uncached session */
+ assert(ctx->sessionID.data == 0);
+ err = SSLAllocBuffer(ctx->sessionID, SSL_SESSION_ID_LEN, ctx);
+ if (err == 0)
+ {
+ if((err = sslRand(ctx, &ctx->sessionID)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+ }
+
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
+ return err;
+ switch (ctx->selectedCipherSpec->keyExchangeMethod)
+ { case SSL_NULL_auth:
+ #if APPLE_DH
+ case SSL_DH_anon:
+ case SSL_DH_anon_EXPORT:
+ if(ctx->clientAuth == kAlwaysAuthenticate) {
+ /* app requires this; abort */
+ SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
+ return errSSLNegotiation;
+ }
+ ctx->tryClientAuth = false;
+ /* DH server side needs work */
+ break;
+ #endif /* APPLE_DH */
+ default: /* everything else */
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
+ ctx)) != 0)
+ return err;
+ break;
+ }
+ /*
+ * At this point we decide whether to send a server key exchange
+ * method. For Apple servers, I think we'll ALWAYS do this, because
+ * of key usage restrictions (can't decrypt and sign with the same
+ * private key), but conceptually in this code, we do it if
+ * enabled by the presence of encryptPrivKey.
+ */
+ #if SSL_SERVER_KEYEXCH_HACK
+ /*
+ * This is currently how we work with Netscape. It requires
+ * a CSP which can handle private keys which can both
+ * sign and decrypt.
+ */
+ if((ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA) &&
+ (ctx->encryptPrivKey != NULL)) {
+ err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
+ if(err) {
+ return err;
+ }
+ }
+ #else /* !SSL_SERVER_KEYEXCH_HACK */
+ /*
+ * This is, I believe the "right" way, but Netscape doesn't
+ * work this way.
+ */
+ if (ctx->encryptPrivKey != NULL) {
+ err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
+ if(err) {
+ return err;
+ }
+ }
+ #endif /* SSL_SERVER_KEYEXCH_HACK */
+
+ if (ctx->tryClientAuth)
+ { if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest,
+ ctx)) != 0)
+ return err;
+ ctx->certRequested = 1;
+ ctx->clientCertState = kSSLClientCertRequested;
+ }
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
+ return err;
+ if (ctx->certRequested) {
+ SSLChangeHdskState(ctx, SSL_HdskStateClientCert);
+ }
+ else {
+ SSLChangeHdskState(ctx, SSL_HdskStateClientKeyExchange);
+ }
+ break;
+ case SSL_HdskServerHello:
+ if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
+ { if ((err = SSLRetrieveSessionID(ctx->resumableSession,
+ &sessionIdentifier, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ if (sessionIdentifier.length == ctx->sessionID.length &&
+ memcmp(sessionIdentifier.data, ctx->sessionID.data,
+ ctx->sessionID.length) == 0)
+ { /* Everything matches; resume the session */
+ sslLogResumSessDebug("===RESUMING SSL3 client-side session");
+ if ((err = SSLInstallSessionFromData(ctx->resumableSession,
+ ctx)) != 0 ||
+ (err = SSLInitPendingCiphers(ctx)) != 0 ||
+ (err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
+ break;
+ }
+ else {
+ sslLogResumSessDebug("===FAILED TO RESUME SSL3 client-side "
+ "session");
+ }
+ if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+ switch (ctx->selectedCipherSpec->keyExchangeMethod)
+ {
+ /* these require a key exchange message */
+ case SSL_NULL_auth:
+ case SSL_DH_anon:
+ case SSL_DH_anon_EXPORT:
+ SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
+ break;
+ case SSL_RSA:
+ case SSL_DH_DSS:
+ case SSL_DH_DSS_EXPORT:
+ case SSL_DH_RSA:
+ case SSL_DH_RSA_EXPORT:
+ case SSL_RSA_EXPORT:
+ case SSL_DHE_DSS:
+ case SSL_DHE_DSS_EXPORT:
+ case SSL_DHE_RSA:
+ case SSL_DHE_RSA_EXPORT:
+ case SSL_Fortezza:
+ SSLChangeHdskState(ctx, SSL_HdskStateCert);
+ break;
+ default:
+ assert("Unknown key exchange method");
+ break;
+ }
+ break;
+ case SSL_HdskCert:
+ if (ctx->state == SSL_HdskStateCert)
+ switch (ctx->selectedCipherSpec->keyExchangeMethod)
+ { case SSL_RSA:
+ /*
+ * I really think the two RSA cases should be
+ * handled the same here - the server key exchange is
+ * optional, and is up to the server.
+ * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
+ * we're a client here.
+ */
+ case SSL_RSA_EXPORT:
+ case SSL_DH_DSS:
+ case SSL_DH_DSS_EXPORT:
+ case SSL_DH_RSA:
+ case SSL_DH_RSA_EXPORT:
+ SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
+ break;
+ case SSL_DHE_DSS:
+ case SSL_DHE_DSS_EXPORT:
+ case SSL_DHE_RSA:
+ case SSL_DHE_RSA_EXPORT:
+ case SSL_Fortezza:
+ SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
+ break;
+ default:
+ assert("Unknown or unexpected key exchange method");
+ break;
+ }
+ else if (ctx->state == SSL_HdskStateClientCert)
+ { SSLChangeHdskState(ctx, SSL_HdskStateClientKeyExchange);
+ if (ctx->peerCert != 0)
+ ctx->certReceived = 1;
+ }
+ break;
+ case SSL_HdskCertRequest:
+ /* state stays in SSL_HdskStateHelloDone; distinction is in
+ * ctx->certRequested */
+ if (ctx->peerCert == 0)
+ { SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
+ return errSSLProtocol;
+ }
+ ctx->certRequested = 1;
+ ctx->clientCertState = kSSLClientCertRequested;
+ break;
+ case SSL_HdskServerKeyExchange:
+ SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
+ break;
+ case SSL_HdskServerHelloDone:
+ if (ctx->certRequested) {
+ /*
+ * Server wants a client authentication cert - do
+ * we have one?
+ */
+ if (ctx->localCert != 0 && ctx->x509Requested) {
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
+ ctx)) != 0) {
+ return err;
+ }
+ }
+ else {
+ /* response for no cert depends on protocol version */
+ if(ctx->negProtocolVersion == TLS_Version_1_0) {
+ /* TLS: send empty cert msg */
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
+ ctx)) != 0) {
+ return err;
+ }
+ }
+ else {
+ /* SSL3: "no cert" alert */
+ if ((err = SSLSendAlert(SSL_AlertLevelWarning, SSL_AlertNoCert,
+ ctx)) != 0) {
+ return err;
+ }
+ }
+ } /* no cert to send */
+ } /* server requested a cert */
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
+ return err;
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
+ (err = SSLInitPendingCiphers(ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
+ if ((err = SSLFreeBuffer(ctx->preMasterSecret, ctx)) != 0) {
+ return err;
+ }
+ if (ctx->certSent) {
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify,
+ ctx)) != 0) {
+ return err;
+ }
+ }
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
+ ctx)) != 0) {
+ return err;
+ }
+ /* Install new cipher spec on write side */
+ if ((err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ ctx->writeCipher = ctx->writePending;
+ /* Can't send data until Finished is sent */
+ ctx->writeCipher.ready = 0;
+
+ /* Zero out old data */
+ memset(&ctx->writePending, 0, sizeof(CipherContext));
+ ctx->writePending.encrypting = 1;
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
+ return err;
+ /* Finished has been sent; enable data transfer on write channel */
+ ctx->writeCipher.ready = 1;
+ SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
+ break;
+ case SSL_HdskCertVerify:
+ SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
+ break;
+ case SSL_HdskClientKeyExchange:
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
+ (err = SSLInitPendingCiphers(ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
+ if ((err = SSLFreeBuffer(ctx->preMasterSecret, ctx)) != 0)
+ return err;
+ if (ctx->certReceived) {
+ SSLChangeHdskState(ctx, SSL_HdskStateClientCertVerify);
+ }
+ else {
+ SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
+ }
+ break;
+ case SSL_HdskFinished:
+ /* Handshake is over; enable data transfer on read channel */
+ ctx->readCipher.ready = 1;
+ /* If writePending is set, we haven't yet sent a finished message;
+ * send it */
+ if (ctx->writePending.ready != 0)
+ { if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
+ ctx)) != 0)
+ return err;
+
+ /* Install new cipher spec on write side */
+ if ((err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ ctx->writeCipher = ctx->writePending;
+ ctx->writeCipher.ready = 0;
+ /* Can't send data until Finished is sent */
+ memset(&ctx->writePending, 0, sizeof(CipherContext));
+ /* Zero out old data */
+ if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
+ ctx)) != 0)
+ return err;
+ ctx->writeCipher.ready = 1;
+ }
+ if (ctx->protocolSide == SSL_ServerSide) {
+ SSLChangeHdskState(ctx, SSL2_HdskStateServerReady);
+ }
+ else {
+ SSLChangeHdskState(ctx, SSL2_HdskStateClientReady);
+ }
+ if (ctx->peerID.data != 0)
+ SSLAddSessionData(ctx);
+ break;
+ default:
+ assert("Unknown State");
+ break;
+ }
+
+ return noErr;
+}
+
+OSStatus
+SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
+{ OSStatus err;
+ SSLRecord rec;
+
+ if ((err = msgFunc(rec, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ goto fail;
+ }
+
+ if (rec.contentType == SSL_RecordTypeHandshake)
+ { if ((err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
+ (err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ goto fail;
+ }
+ SSLLogHdskMsg((SSLHandshakeType)rec.contents.data[0], 1);
+ }
+
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+ goto fail;
+
+ err = noErr;
+fail:
+ SSLFreeBuffer(rec.contents, ctx);
+
+ return err;
+}
+
+OSStatus
+SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
+{ OSStatus err;
+
+ if ((err = SSLInitMessageHashes(ctx)) != 0)
+ return err;
+
+ if ((err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
+ (err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+
+ if ((err = SSLAdvanceHandshake(SSL_HdskClientHello, ctx)) != 0)
+ return err;
+
+ return noErr;
+}
+
+/* log changes in handshake state */
+#ifndef NDEBUG
+#include <stdio.h>
+
+char *hdskStateToStr(SSLHandshakeState state)
+{
+ static char badStr[100];
+
+ switch(state) {
+ case SSL_HdskStateUninit:
+ return "Uninit";
+ case SSL_HdskStateServerUninit:
+ return "ServerUninit";
+ case SSL_HdskStateClientUninit:
+ return "ClientUninit";
+ case SSL_HdskStateGracefulClose:
+ return "GracefulClose";
+ case SSL_HdskStateErrorClose:
+ return "ErrorClose";
+ case SSL_HdskStateNoNotifyClose:
+ return "NoNotifyClose";
+ case SSL_HdskStateServerHello:
+ return "ServerHello";
+ case SSL_HdskStateServerHelloUnknownVersion:
+ return "ServerHelloUnknownVersion";
+ case SSL_HdskStateKeyExchange:
+ return "KeyExchange";
+ case SSL_HdskStateCert:
+ return "Cert";
+ case SSL_HdskStateHelloDone:
+ return "HelloDone";
+ case SSL_HdskStateClientCert:
+ return "ClientCert";
+ case SSL_HdskStateClientKeyExchange:
+ return "ClientKeyExchange";
+ case SSL_HdskStateClientCertVerify:
+ return "ClientCertVerify";
+ case SSL_HdskStateChangeCipherSpec:
+ return "ChangeCipherSpec";
+ case SSL_HdskStateFinished:
+ return "Finished";
+ case SSL2_HdskStateClientMasterKey:
+ return "SSL2_ClientMasterKey";
+ case SSL2_HdskStateClientFinished:
+ return "SSL2_ClientFinished";
+ case SSL2_HdskStateServerHello:
+ return "SSL2_ServerHello";
+ case SSL2_HdskStateServerVerify:
+ return "SSL2_ServerVerify";
+ case SSL2_HdskStateServerFinished:
+ return "SSL2_ServerFinished";
+ case SSL2_HdskStateServerReady:
+ return "SSL2_ServerReady";
+ case SSL2_HdskStateClientReady:
+ return "SSL2_ClientReady";
+ default:
+ sprintf(badStr, "Unknown state (%d(d)", state);
+ return badStr;
+ }
+}
+
+void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
+{
+ /* FIXME - this ifndef should not be necessary */
+ #ifndef NDEBUG
+ sslHdskStateDebug("...hdskState = %s", hdskStateToStr(newState));
+ #endif
+ ctx->state = newState;
+}
+
+
+/* log handshake messages */
+
+static char *hdskMsgToStr(SSLHandshakeType msg)
+{
+ static char badStr[100];
+
+ switch(msg) {
+ case SSL_HdskHelloRequest:
+ return "SSL_HdskHelloRequest";
+ case SSL_HdskClientHello:
+ return "SSL_HdskClientHello";
+ case SSL_HdskServerHello:
+ return "SSL_HdskServerHello";
+ case SSL_HdskCert:
+ return "SSL_HdskCert";
+ case SSL_HdskServerKeyExchange:
+ return "SSL_HdskServerKeyExchange";
+ case SSL_HdskCertRequest:
+ return "SSL_HdskCertRequest";
+ case SSL_HdskServerHelloDone:
+ return "SSL_HdskServerHelloDone";
+ case SSL_HdskCertVerify:
+ return "SSL_HdskCertVerify";
+ case SSL_HdskClientKeyExchange:
+ return "SSL_HdskClientKeyExchange";
+ case SSL_HdskFinished:
+ return "SSL_HdskFinished";
+ case SSL_HdskNoCertAlert:
+ return "SSL_HdskNoCertAlert";
+ default:
+ sprintf(badStr, "Unknown state (%d(d)", msg);
+ return badStr;
+ }
+}
+
+void SSLLogHdskMsg(SSLHandshakeType msg, char sent)
+{
+ sslHdskMsgDebug("---%s handshake msg %s",
+ hdskMsgToStr(msg), (sent ? "sent" : "recv"));
+}
+
+#endif /* NDEBUG */
+
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslHandshakeFinish.c
+
+ Contains: Finished and server hello done messages.
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslMemory.h"
+#include "sslDebug.h"
+#include "sslUtils.h"
+#include "sslDigests.h"
+
+#include <string.h>
+#include <assert.h>
+
+OSStatus
+SSLEncodeFinishedMessage(SSLRecord &finished, SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer finishedMsg, shaMsgState, md5MsgState;
+ Boolean isServerMsg;
+ unsigned finishedSize;
+
+ shaMsgState.data = 0;
+ md5MsgState.data = 0;
+
+ /* size and version depend on negotiatedProtocol */
+ switch(ctx->negProtocolVersion) {
+ case SSL_Version_3_0:
+ finished.protocolVersion = SSL_Version_3_0;
+ finishedSize = 36;
+ break;
+ case TLS_Version_1_0:
+ finished.protocolVersion = TLS_Version_1_0;
+ finishedSize = 12;
+ break;
+ default:
+ assert(0);
+ return errSSLInternal;
+ }
+ finished.contentType = SSL_RecordTypeHandshake;
+ /* msg = type + 3 bytes len + finishedSize */
+ if ((err = SSLAllocBuffer(finished.contents, finishedSize + 4,
+ ctx)) != 0)
+ return err;
+
+ finished.contents.data[0] = SSL_HdskFinished;
+ SSLEncodeInt(finished.contents.data + 1, finishedSize, 3);
+
+ finishedMsg.data = finished.contents.data + 4;
+ finishedMsg.length = finishedSize;
+
+ if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
+ goto fail;
+ if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
+ goto fail;
+ isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? true : false;
+ if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, finishedMsg,
+ shaMsgState, md5MsgState, isServerMsg)) != 0)
+ goto fail;
+
+fail:
+ SSLFreeBuffer(shaMsgState, ctx);
+ SSLFreeBuffer(md5MsgState, ctx);
+ return err;
+}
+
+OSStatus
+SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer expectedFinished, shaMsgState, md5MsgState;
+ Boolean isServerMsg;
+ unsigned finishedSize;
+
+ switch(ctx->negProtocolVersion) {
+ case SSL_Version_3_0:
+ finishedSize = 36;
+ break;
+ case TLS_Version_1_0:
+ finishedSize = 12;
+ break;
+ default:
+ assert(0);
+ return errSSLInternal;
+ }
+ if (message.length != finishedSize) {
+ sslErrorLog("SSLProcessFinished: msg len error 1\n");
+ return errSSLProtocol;
+ }
+ expectedFinished.data = 0;
+ if ((err = SSLAllocBuffer(expectedFinished, finishedSize, ctx)) != 0)
+ return err;
+ shaMsgState.data = 0;
+ if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
+ goto fail;
+ md5MsgState.data = 0;
+ if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
+ goto fail;
+ isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? false : true;
+ if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished,
+ shaMsgState, md5MsgState, isServerMsg)) != 0)
+ goto fail;
+
+ if (memcmp(expectedFinished.data, message.data, finishedSize) != 0)
+ {
+ sslErrorLog("SSLProcessFinished: memcmp failure\n");
+ err = errSSLProtocol;
+ goto fail;
+ }
+
+fail:
+ SSLFreeBuffer(expectedFinished, ctx);
+ SSLFreeBuffer(shaMsgState, ctx);
+ SSLFreeBuffer(md5MsgState, ctx);
+ return err;
+}
+
+OSStatus
+SSLEncodeServerHelloDone(SSLRecord &helloDone, SSLContext *ctx)
+{ OSStatus err;
+
+ helloDone.contentType = SSL_RecordTypeHandshake;
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ helloDone.protocolVersion = ctx->negProtocolVersion;
+ if ((err = SSLAllocBuffer(helloDone.contents, 4, ctx)) != 0)
+ return err;
+ helloDone.contents.data[0] = SSL_HdskServerHelloDone;
+ SSLEncodeInt(helloDone.contents.data+1, 0, 3); /* Message has 0 length */
+ return noErr;
+}
+
+OSStatus
+SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
+{ assert(ctx->protocolSide == SSL_ClientSide);
+ if (message.length != 0) {
+ sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
+ return errSSLProtocol;
+ }
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslHandshakeHello.c
+
+ Contains: Support for client hello and server hello messages.
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslMemory.h"
+#include "sslSession.h"
+#include "sslUtils.h"
+#include "sslDebug.h"
+#include "appleCdsa.h"
+#include "sslDigests.h"
+#include "cipherSpecs.h"
+
+#include <string.h>
+
+static OSStatus SSLEncodeRandom(unsigned char *p, SSLContext *ctx);
+
+/* IE treats null session id as valid; two consecutive sessions with NULL ID
+ * are considered a match. Workaround: when resumable sessions are disabled,
+ * send a random session ID. */
+#define SSL_IE_NULL_RESUME_BUG 1
+#if SSL_IE_NULL_RESUME_BUG
+#define SSL_NULL_ID_LEN 32 /* length of bogus session ID */
+#endif
+
+OSStatus
+SSLEncodeServerHello(SSLRecord &serverHello, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 *charPtr;
+ int sessionIDLen;
+
+ sessionIDLen = 0;
+ if (ctx->sessionID.data != 0)
+ sessionIDLen = (UInt8)ctx->sessionID.length;
+ #if SSL_IE_NULL_RESUME_BUG
+ if(sessionIDLen == 0) {
+ sessionIDLen = SSL_NULL_ID_LEN;
+ }
+ #endif /* SSL_IE_NULL_RESUME_BUG */
+
+ sslLogNegotiateDebug("===SSL3 server: sending version %d_%d",
+ ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
+ sslLogNegotiateDebug("...sessionIDLen = %d", sessionIDLen);
+ serverHello.protocolVersion = ctx->negProtocolVersion;
+ serverHello.contentType = SSL_RecordTypeHandshake;
+ if ((err = SSLAllocBuffer(serverHello.contents, 42 + sessionIDLen, ctx)) != 0)
+ return err;
+
+ charPtr = serverHello.contents.data;
+ *charPtr++ = SSL_HdskServerHello;
+ charPtr = SSLEncodeInt(charPtr, 38 + sessionIDLen, 3);
+ charPtr = SSLEncodeInt(charPtr, serverHello.protocolVersion, 2);
+ if ((err = SSLEncodeRandom(charPtr, ctx)) != 0)
+ return err;
+ memcpy(ctx->serverRandom, charPtr, SSL_CLIENT_SRVR_RAND_SIZE);
+ charPtr += SSL_CLIENT_SRVR_RAND_SIZE;
+ *(charPtr++) = (UInt8)sessionIDLen;
+ #if SSL_IE_NULL_RESUME_BUG
+ if(ctx->sessionID.data != NULL) {
+ /* normal path for enabled resumable session */
+ memcpy(charPtr, ctx->sessionID.data, sessionIDLen);
+ }
+ else {
+ /* IE workaround */
+ SSLBuffer rb;
+ rb.data = charPtr;
+ rb.length = SSL_NULL_ID_LEN;
+ sslRand(ctx, &rb);
+ }
+ #else
+ if (sessionIDLen > 0)
+ memcpy(charPtr, ctx->sessionID.data, sessionIDLen);
+ #endif /* SSL_IE_NULL_RESUME_BUG */
+ charPtr += sessionIDLen;
+ charPtr = SSLEncodeInt(charPtr, ctx->selectedCipher, 2);
+ *(charPtr++) = 0; /* Null compression */
+
+ sslLogNegotiateDebug("ssl3: server specifying cipherSuite 0x%lx",
+ (UInt32)ctx->selectedCipher);
+
+ assert(charPtr == serverHello.contents.data + serverHello.contents.length);
+
+ return noErr;
+}
+
+OSStatus
+SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
+{ OSStatus err;
+ SSLProtocolVersion protocolVersion;
+ unsigned int sessionIDLen;
+ UInt8 *p;
+
+ assert(ctx->protocolSide == SSL_ClientSide);
+
+ if (message.length < 38 || message.length > 70) {
+ sslErrorLog("SSLProcessServerHello: msg len error\n");
+ return errSSLProtocol;
+ }
+ p = message.data;
+
+ protocolVersion = (SSLProtocolVersion)SSLDecodeInt(p, 2);
+ p += 2;
+ if (protocolVersion > ctx->maxProtocolVersion) {
+ return errSSLNegotiation;
+ }
+ ctx->negProtocolVersion = protocolVersion;
+ switch(protocolVersion) {
+ case SSL_Version_3_0:
+ ctx->sslTslCalls = &Ssl3Callouts;
+ break;
+ case TLS_Version_1_0:
+ ctx->sslTslCalls = &Tls1Callouts;
+ break;
+ default:
+ return errSSLNegotiation;
+ }
+ sslLogNegotiateDebug("===SSL3 client: negVersion is %d_%d",
+ (protocolVersion >> 8) & 0xff, protocolVersion & 0xff);
+
+ memcpy(ctx->serverRandom, p, 32);
+ p += 32;
+
+ sessionIDLen = *p++;
+ if (message.length != 38 + sessionIDLen) {
+ sslErrorLog("SSLProcessServerHello: msg len error 2\n");
+ return errSSLProtocol;
+ }
+ if (sessionIDLen > 0 && ctx->peerID.data != 0)
+ { /* Don't die on error; just treat it as an uncached session */
+ err = SSLAllocBuffer(ctx->sessionID, sessionIDLen, ctx);
+ if (err == 0)
+ memcpy(ctx->sessionID.data, p, sessionIDLen);
+ }
+ p += sessionIDLen;
+
+ ctx->selectedCipher = (UInt16)SSLDecodeInt(p,2);
+ sslLogNegotiateDebug("===ssl3: server requests cipherKind %d",
+ (unsigned)ctx->selectedCipher);
+ p += 2;
+ if ((err = FindCipherSpec(ctx)) != 0) {
+ return err;
+ }
+
+ if (*p++ != 0) /* Compression */
+ return unimpErr;
+
+ assert(p == message.data + message.length);
+ return noErr;
+}
+
+OSStatus
+SSLEncodeClientHello(SSLRecord &clientHello, SSLContext *ctx)
+{
+ unsigned length, i;
+ OSStatus err;
+ unsigned char *p;
+ SSLBuffer sessionIdentifier;
+ UInt16 sessionIDLen;
+
+ assert(ctx->protocolSide == SSL_ClientSide);
+
+ sessionIDLen = 0;
+ if (ctx->resumableSession.data != 0)
+ { if ((err = SSLRetrieveSessionID(ctx->resumableSession,
+ &sessionIdentifier, ctx)) != 0)
+ { return err;
+ }
+ sessionIDLen = sessionIdentifier.length;
+ }
+
+ length = 39 + 2*(ctx->numValidCipherSpecs) + sessionIDLen;
+
+ clientHello.protocolVersion = ctx->maxProtocolVersion;
+ clientHello.contentType = SSL_RecordTypeHandshake;
+ if ((err = SSLAllocBuffer(clientHello.contents, length + 4, ctx)) != 0)
+ return err;
+
+ p = clientHello.contents.data;
+ *p++ = SSL_HdskClientHello;
+ p = SSLEncodeInt(p, length, 3);
+ p = SSLEncodeInt(p, ctx->maxProtocolVersion, 2);
+ sslLogNegotiateDebug("===SSL3 client: proclaiming max protocol "
+ "%d_%d capable ONLY",
+ ctx->maxProtocolVersion >> 8, ctx->maxProtocolVersion & 0xff);
+ if ((err = SSLEncodeRandom(p, ctx)) != 0)
+ { SSLFreeBuffer(clientHello.contents, ctx);
+ return err;
+ }
+ memcpy(ctx->clientRandom, p, SSL_CLIENT_SRVR_RAND_SIZE);
+ p += 32;
+ *p++ = sessionIDLen; /* 1 byte vector length */
+ if (sessionIDLen > 0)
+ { memcpy(p, sessionIdentifier.data, sessionIDLen);
+ if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
+ return err;
+ }
+ p += sessionIDLen;
+ p = SSLEncodeInt(p, 2*(ctx->numValidCipherSpecs), 2);
+ /* 2 byte long vector length */
+ for (i = 0; i<ctx->numValidCipherSpecs; ++i)
+ p = SSLEncodeInt(p, ctx->validCipherSpecs[i].cipherSpec, 2);
+ *p++ = 1; /* 1 byte long vector */
+ *p++ = 0; /* null compression */
+
+ assert(p == clientHello.contents.data + clientHello.contents.length);
+
+ if ((err = SSLInitMessageHashes(ctx)) != 0)
+ return err;
+
+ return noErr;
+}
+
+OSStatus
+SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
+{ OSStatus err;
+ SSLProtocolVersion clientVersion;
+ UInt16 cipherListLen, cipherCount, desiredSpec, cipherSpec;
+ UInt8 sessionIDLen, compressionCount;
+ UInt8 *charPtr;
+ unsigned i;
+
+ if (message.length < 41) {
+ sslErrorLog("SSLProcessClientHello: msg len error 1\n");
+ return errSSLProtocol;
+ }
+ charPtr = message.data;
+ clientVersion = (SSLProtocolVersion)SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ if(clientVersion > ctx->maxProtocolVersion) {
+ clientVersion = ctx->maxProtocolVersion;
+ }
+ switch(clientVersion) {
+ case SSL_Version_3_0:
+ ctx->sslTslCalls = &Ssl3Callouts;
+ break;
+ case TLS_Version_1_0:
+ ctx->sslTslCalls = &Tls1Callouts;
+ break;
+ default:
+ return errSSLNegotiation;
+ }
+ ctx->negProtocolVersion = clientVersion;
+ sslLogNegotiateDebug("===SSL3 server: negVersion is %d_%d",
+ clientVersion >> 8, clientVersion & 0xff);
+
+ memcpy(ctx->clientRandom, charPtr, SSL_CLIENT_SRVR_RAND_SIZE);
+ charPtr += 32;
+ sessionIDLen = *(charPtr++);
+ if (message.length < (unsigned)(41 + sessionIDLen)) {
+ sslErrorLog("SSLProcessClientHello: msg len error 2\n");
+ return errSSLProtocol;
+ }
+ if (sessionIDLen > 0 && ctx->peerID.data != 0)
+ { /* Don't die on error; just treat it as an uncacheable session */
+ err = SSLAllocBuffer(ctx->sessionID, sessionIDLen, ctx);
+ if (err == 0)
+ memcpy(ctx->sessionID.data, charPtr, sessionIDLen);
+ }
+ charPtr += sessionIDLen;
+
+ cipherListLen = (UInt16)SSLDecodeInt(charPtr, 2);
+ /* Count of cipherSpecs, must be even & >= 2 */
+ charPtr += 2;
+ if ((cipherListLen & 1) ||
+ (cipherListLen < 2) ||
+ (message.length < (unsigned)(39 + sessionIDLen + cipherListLen))) {
+ sslErrorLog("SSLProcessClientHello: msg len error 3\n");
+ return errSSLProtocol;
+ }
+ cipherCount = cipherListLen/2;
+ cipherSpec = 0xFFFF; /* No match marker */
+ while (cipherSpec == 0xFFFF && cipherCount--)
+ { desiredSpec = (UInt16)SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ for (i = 0; i <ctx->numValidCipherSpecs; i++)
+ { if (ctx->validCipherSpecs[i].cipherSpec == desiredSpec)
+ { cipherSpec = desiredSpec;
+ break;
+ }
+ }
+ }
+
+ if (cipherSpec == 0xFFFF)
+ return errSSLNegotiation;
+ charPtr += 2 * cipherCount; /* Advance past unchecked cipherCounts */
+ ctx->selectedCipher = cipherSpec;
+ if ((err = FindCipherSpec(ctx)) != 0) {
+ return err;
+ }
+ sslLogNegotiateDebug("ssl3 server: selecting cipherKind 0x%x", (unsigned)ctx->selectedCipher);
+
+ compressionCount = *(charPtr++);
+ if ((compressionCount < 1) ||
+ (message.length <
+ (unsigned)(38 + sessionIDLen + cipherListLen + compressionCount))) {
+ sslErrorLog("SSLProcessClientHello: msg len error 4\n");
+ return errSSLProtocol;
+ }
+ /* Ignore list; we're doing null */
+
+ if ((err = SSLInitMessageHashes(ctx)) != 0)
+ return err;
+
+ return noErr;
+}
+
+static OSStatus
+SSLEncodeRandom(unsigned char *p, SSLContext *ctx)
+{ SSLBuffer randomData;
+ OSStatus err;
+ UInt32 time;
+
+ if ((err = sslTime(&time)) != 0)
+ return err;
+ SSLEncodeInt(p, time, 4);
+ randomData.data = p+4;
+ randomData.length = 28;
+ if((err = sslRand(ctx, &randomData)) != 0)
+ return err;
+ return noErr;
+}
+
+OSStatus
+SSLInitMessageHashes(SSLContext *ctx)
+{ OSStatus err;
+
+ if ((err = CloseHash(SSLHashSHA1, ctx->shaState, ctx)) != 0)
+ return err;
+ if ((err = CloseHash(SSLHashMD5, ctx->md5State, ctx)) != 0)
+ return err;
+ if ((err = ReadyHash(SSLHashSHA1, ctx->shaState, ctx)) != 0)
+ return err;
+ if ((err = ReadyHash(SSLHashMD5, ctx->md5State, ctx)) != 0)
+ return err;
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslKeyExchange.c
+
+ Contains: Support for key exchange and server key exchange
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslMemory.h"
+#include "sslDebug.h"
+#include "sslUtils.h"
+#include "appleCdsa.h"
+#include "sslDigests.h"
+
+#include <assert.h>
+#include <string.h>
+
+/*
+ * Client RSA Key Exchange msgs actually start with a two-byte
+ * length field, contrary to the first version of RFC 2246, dated
+ * January 1999. See RFC 2246, March 2002, section 7.4.7.1 for
+ * updated requirements.
+ */
+#define RSA_CLIENT_KEY_ADD_LENGTH 1
+
+typedef CSSM_KEY_PTR SSLRSAPrivateKey;
+
+static OSStatus SSLEncodeRSAServerKeyExchange(SSLRecord &keyExch, SSLContext *ctx);
+static OSStatus SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx);
+static OSStatus SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx);
+static OSStatus SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
+static OSStatus SSLEncodeRSAKeyExchange(SSLRecord &keyExchange, SSLContext *ctx);
+#if APPLE_DH
+static OSStatus SSLEncodeDHanonServerKeyExchange(SSLRecord &keyExch, SSLContext *ctx);
+static OSStatus SSLEncodeDHanonKeyExchange(SSLRecord &keyExchange, SSLContext *ctx);
+static OSStatus SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
+static OSStatus SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx);
+#endif
+
+OSStatus
+SSLEncodeServerKeyExchange(SSLRecord &keyExch, SSLContext *ctx)
+{ OSStatus err;
+
+ switch (ctx->selectedCipherSpec->keyExchangeMethod)
+ { case SSL_RSA:
+ case SSL_RSA_EXPORT:
+ if ((err = SSLEncodeRSAServerKeyExchange(keyExch, ctx)) != 0)
+ return err;
+ break;
+ #if APPLE_DH
+ case SSL_DH_anon:
+ if ((err = SSLEncodeDHanonServerKeyExchange(keyExch, ctx)) != 0)
+ return err;
+ break;
+ #endif
+ default:
+ return unimpErr;
+ }
+
+ return noErr;
+}
+
+static OSStatus
+SSLEncodeRSAServerKeyExchange(SSLRecord &keyExch, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 *charPtr;
+ int length;
+ UInt32 outputLen, localKeyModulusLen;
+ UInt8 hashes[36];
+ SSLBuffer exportKey,clientRandom,serverRandom,hashCtx, hash;
+
+ exportKey.data = 0;
+ hashCtx.data = 0;
+
+ /* we have a public key here... */
+ assert(ctx->encryptPubKey != NULL);
+ assert(ctx->protocolSide == SSL_ServerSide);
+
+ if ((err = SSLEncodeRSAKeyParams(&exportKey, &ctx->encryptPubKey, ctx)) != 0)
+ goto fail;
+
+ assert(ctx->signingPubKey != NULL);
+ localKeyModulusLen = sslKeyLengthInBytes(ctx->signingPubKey);
+
+ length = exportKey.length + 2 + localKeyModulusLen;
+ /* RSA ouputs a block as long as the modulus */
+
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ keyExch.protocolVersion = ctx->negProtocolVersion;
+ keyExch.contentType = SSL_RecordTypeHandshake;
+ if ((err = SSLAllocBuffer(keyExch.contents, length+4, ctx)) != 0)
+ goto fail;
+
+ charPtr = keyExch.contents.data;
+ *charPtr++ = SSL_HdskServerKeyExchange;
+ charPtr = SSLEncodeInt(charPtr, length, 3);
+
+ memcpy(charPtr, exportKey.data, exportKey.length);
+ charPtr += exportKey.length;
+
+ clientRandom.data = ctx->clientRandom;
+ clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ serverRandom.data = ctx->serverRandom;
+ serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+
+ hash.data = &hashes[0];
+ hash.length = 16;
+ if ((err = ReadyHash(SSLHashMD5, hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, exportKey)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.final(hashCtx, hash)) != 0)
+ goto fail;
+ if ((err = SSLFreeBuffer(hashCtx, ctx)) != 0)
+ goto fail;
+
+ hash.data = &hashes[16];
+ hash.length = 20;
+ if ((err = ReadyHash(SSLHashSHA1, hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(hashCtx, exportKey)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.final(hashCtx, hash)) != 0)
+ goto fail;
+ if ((err = SSLFreeBuffer(hashCtx, ctx)) != 0)
+ goto fail;
+
+ charPtr = SSLEncodeInt(charPtr, localKeyModulusLen, 2);
+ err = sslRsaRawSign(ctx,
+ ctx->signingPrivKey,
+ ctx->signingKeyCsp,
+ hashes,
+ 36,
+ charPtr,
+ length,
+ &outputLen);
+ if(err) {
+ goto fail;
+ }
+ assert(outputLen == localKeyModulusLen);
+
+ err = noErr;
+
+fail:
+ SSLFreeBuffer(hashCtx, ctx);
+ SSLFreeBuffer(exportKey, ctx);
+
+ return err;
+}
+
+static OSStatus
+SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer modulus, exponent;
+ UInt8 *charPtr;
+
+ err = sslGetPubKeyBits(ctx,
+ *key,
+ ctx->encryptKeyCsp,
+ &modulus,
+ &exponent);
+ if(err) {
+ SSLFreeBuffer(modulus, ctx);
+ SSLFreeBuffer(exponent, ctx);
+ return err;
+ }
+
+ if ((err = SSLAllocBuffer(*keyParams, modulus.length + exponent.length + 4, ctx)) != 0)
+ return err;
+ charPtr = keyParams->data;
+ charPtr = SSLEncodeInt(charPtr, modulus.length, 2);
+ memcpy(charPtr, modulus.data, modulus.length);
+ charPtr += modulus.length;
+ charPtr = SSLEncodeInt(charPtr, exponent.length, 2);
+ memcpy(charPtr, exponent.data, exponent.length);
+
+ /* these were mallocd by sslGetPubKeyBits() */
+ SSLFreeBuffer(modulus, ctx);
+ SSLFreeBuffer(exponent, ctx);
+ return noErr;
+}
+
+#if APPLE_DH
+static OSStatus
+SSLEncodeDHanonServerKeyExchange(SSLRecord &keyExch, SSLContext *ctx)
+{ OSStatus err;
+ UInt32 length;
+ UInt8 *charPtr;
+ SSLRandomCtx random;
+ int rsaErr;
+
+#if RSAREF
+ length = 6 + ctx->dhAnonParams.primeLen + ctx->dhAnonParams.generatorLen +
+ ctx->dhExchangePublic.length;
+
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ keyExch.protocolVersion = ctx->negProtocolVersion;
+ keyExch.contentType = SSL_RecordTypeHandshake;
+ if ((err = SSLAllocBuffer(keyExch.contents, length+4, ctx)) != 0)
+ return err;
+
+ charPtr = keyExch.contents.data;
+ *charPtr++ = SSL_HdskServerKeyExchange;
+ charPtr = SSLEncodeInt(charPtr, length, 3);
+
+ charPtr = SSLEncodeInt(charPtr, ctx->dhAnonParams.primeLen, 2);
+ memcpy(charPtr, ctx->dhAnonParams.prime, ctx->dhAnonParams.primeLen);
+ charPtr += ctx->dhAnonParams.primeLen;
+
+ charPtr = SSLEncodeInt(charPtr, ctx->dhAnonParams.generatorLen, 2);
+ memcpy(charPtr, ctx->dhAnonParams.generator, ctx->dhAnonParams.generatorLen);
+ charPtr += ctx->dhAnonParams.generatorLen;
+
+ if ((err = SSLAllocBuffer(ctx->dhExchangePublic,
+ ctx->peerDHParams.primeLen, ctx)) != 0)
+ return err;
+ if ((err = SSLAllocBuffer(ctx->dhPrivate,
+ ctx->dhExchangePublic.length - 16, ctx)) != 0)
+ return err;
+
+ if ((err = ReadyRandom(&random, ctx)) != 0)
+ return err;
+
+ if ((rsaErr = R_SetupDHAgreement(ctx->dhExchangePublic.data, ctx->dhPrivate.data,
+ ctx->dhPrivate.length, &ctx->dhAnonParams, &random)) != 0)
+ { err = SSLUnknownErr;
+ return err;
+ }
+
+ charPtr = SSLEncodeInt(charPtr, ctx->dhExchangePublic.length, 2);
+ memcpy(charPtr, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
+ charPtr += ctx->dhExchangePublic.length;
+
+#elif BSAFE
+ { A_DH_KEY_AGREE_PARAMS *params;
+ unsigned int outputLen;
+
+ if ((rsaErr = B_GetAlgorithmInfo((POINTER*)¶ms, ctx->dhAnonParams, AI_DHKeyAgree)) != 0)
+ return SSLUnknownErr;
+ if ((err = ReadyRandom(&random, ctx)) != 0)
+ return err;
+ if ((err = SSLAllocBuffer(ctx->dhExchangePublic, 128, ctx)) != 0)
+ return err;
+ if ((rsaErr = B_KeyAgreePhase1(ctx->dhAnonParams, ctx->dhExchangePublic.data,
+ &outputLen, 128, random, NO_SURR)) != 0)
+ { err = SSLUnknownErr;
+ return err;
+ }
+ ctx->dhExchangePublic.length = outputLen;
+
+ length = 6 + params->prime.len + params->base.len + ctx->dhExchangePublic.length;
+
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ keyExch.protocolVersion = ctx->negProtocolVersion;
+ keyExch.contentType = SSL_RecordTypeHandshake;
+ if ((err = SSLAllocBuffer(keyExch.contents, length+4, ctx)) != 0)
+ return err;
+
+ charPtr = keyExch.contents.data;
+ *charPtr++ = SSL_HdskServerKeyExchange;
+ charPtr = SSLEncodeInt(charPtr, length, 3);
+
+ charPtr = SSLEncodeInt(charPtr, params->prime.len, 2);
+ memcpy(charPtr, params->prime.data, params->prime.len);
+ charPtr += params->prime.len;
+
+ charPtr = SSLEncodeInt(charPtr, params->base.len, 2);
+ memcpy(charPtr, params->base.data, params->base.len);
+ charPtr += params->base.len;
+
+ charPtr = SSLEncodeInt(charPtr, ctx->dhExchangePublic.length, 2);
+ memcpy(charPtr, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
+ charPtr += ctx->dhExchangePublic.length;
+ }
+#endif /* RSAREF / BSAFE */
+
+ assert(charPtr == keyExch.contents.data + keyExch.contents.length);
+
+ return noErr;
+}
+
+#endif /* APPLE_DH */
+
+OSStatus
+SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
+{ OSStatus err;
+
+ switch (ctx->selectedCipherSpec->keyExchangeMethod)
+ { case SSL_RSA:
+ case SSL_RSA_EXPORT:
+ if ((err = SSLProcessRSAServerKeyExchange(message, ctx)) != 0)
+ return err;
+ break;
+ #if APPLE_DH
+ case SSL_DH_anon:
+ if ((err = SSLProcessDHanonServerKeyExchange(message, ctx)) != 0)
+ return err;
+ break;
+ #endif
+ default:
+ return unimpErr;
+ }
+
+ return noErr;
+}
+
+static OSStatus
+SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx)
+{
+ OSStatus err;
+ SSLBuffer tempPubKey, hashOut, hashCtx, clientRandom, serverRandom;
+ UInt16 modulusLen, exponentLen, signatureLen;
+ UInt8 *charPtr, *modulus, *exponent, *signature;
+ UInt8 hash[36];
+ SSLBuffer signedHashes;
+
+ signedHashes.data = 0;
+ hashCtx.data = 0;
+
+ if (message.length < 2) {
+ sslErrorLog("SSLProcessRSAServerKeyExchange: msg len error 2\n");
+ return errSSLProtocol;
+ }
+ charPtr = message.data;
+ modulusLen = SSLDecodeInt(charPtr, 2);
+ modulus = charPtr + 2;
+ charPtr += 2+modulusLen;
+ if (message.length < (unsigned)(4 + modulusLen)) {
+ sslErrorLog("SSLProcessRSAServerKeyExchange: msg len error 2\n");
+ return errSSLProtocol;
+ }
+ exponentLen = SSLDecodeInt(charPtr, 2);
+ exponent = charPtr + 2;
+ charPtr += 2+exponentLen;
+ if (message.length < (unsigned)(6 + modulusLen + exponentLen)) {
+ sslErrorLog("SSLProcessRSAServerKeyExchange: msg len error 2\n");
+ return errSSLProtocol;
+ }
+ signatureLen = SSLDecodeInt(charPtr, 2);
+ signature = charPtr + 2;
+ if (message.length != (unsigned)(6 + modulusLen + exponentLen + signatureLen)) {
+ sslErrorLog("SSLProcessRSAServerKeyExchange: msg len error 3\n");
+ return errSSLProtocol;
+ }
+
+ clientRandom.data = ctx->clientRandom;
+ clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ serverRandom.data = ctx->serverRandom;
+ serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
+ tempPubKey.data = message.data;
+ tempPubKey.length = modulusLen + exponentLen + 4;
+ hashOut.data = hash;
+
+ hashOut.length = 16;
+ if ((err = ReadyHash(SSLHashMD5, hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.update(hashCtx, tempPubKey)) != 0)
+ goto fail;
+ if ((err = SSLHashMD5.final(hashCtx, hashOut)) != 0)
+ goto fail;
+
+ /*
+ * SHA hash goes right after the MD5 hash
+ */
+ hashOut.data = hash + 16;
+ hashOut.length = 20;
+ if ((err = SSLFreeBuffer(hashCtx, ctx)) != 0)
+ goto fail;
+
+ if ((err = ReadyHash(SSLHashSHA1, hashCtx, ctx)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.update(hashCtx, tempPubKey)) != 0)
+ goto fail;
+ if ((err = SSLHashSHA1.final(hashCtx, hashOut)) != 0)
+ goto fail;
+
+ err = sslRsaRawVerify(ctx,
+ ctx->peerPubKey,
+ ctx->peerPubKeyCsp,
+ hash, /* plaintext */
+ 36, /* plaintext length */
+ signature,
+ signatureLen);
+ if(err) {
+ sslErrorLog("SSLProcessRSAServerKeyExchange: sslRsaRawVerify returned %d\n",
+ (int)err);
+ goto fail;
+ }
+
+ /* Signature matches; now replace server key with new key */
+ {
+ SSLBuffer modBuf;
+ SSLBuffer expBuf;
+
+ /* first free existing peerKey */
+ sslFreeKey(ctx->peerPubKeyCsp,
+ &ctx->peerPubKey,
+ NULL); /* no KCItem */
+
+ /* and cook up a new one from raw bits */
+ modBuf.data = modulus;
+ modBuf.length = modulusLen;
+ expBuf.data = exponent;
+ expBuf.length = exponentLen;
+ err = sslGetPubKeyFromBits(ctx,
+ &modBuf,
+ &expBuf,
+ &ctx->peerPubKey,
+ &ctx->peerPubKeyCsp);
+ }
+fail:
+ SSLFreeBuffer(signedHashes, ctx);
+ SSLFreeBuffer(hashCtx, ctx);
+ return err;
+}
+
+#if APPLE_DH
+static OSStatus
+SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
+{ OSStatus err;
+ UInt8 *charPtr;
+ unsigned int totalLength;
+
+ if (message.length < 6) {
+ sslErrorLog("SSLProcessDHanonServerKeyExchange error: msg len %d\n",
+ message.length);
+ return errSSLProtocol;
+ }
+ charPtr = message.data;
+ totalLength = 0;
+
+#if RSAREF
+ { SSLBuffer alloc;
+ UInt8 *prime, *generator, *publicVal;
+
+ ctx->peerDHParams.primeLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ prime = charPtr;
+ charPtr += ctx->peerDHParams.primeLen;
+ totalLength += ctx->peerDHParams.primeLen;
+ if (message.length < 6 + totalLength)
+ return errSSLProtocol;
+
+ ctx->peerDHParams.generatorLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ generator = charPtr;
+ charPtr += ctx->peerDHParams.generatorLen;
+ totalLength += ctx->peerDHParams.generatorLen;
+ if (message.length < 6 + totalLength)
+ return errSSLProtocol;
+
+ ctx->dhPeerPublic.length = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ publicVal = charPtr;
+ charPtr += ctx->dhPeerPublic.length;
+ totalLength += ctx->dhPeerPublic.length;
+ if (message.length != 6 + totalLength)
+ return errSSLProtocol;
+
+ assert(charPtr == message.data + message.length);
+
+ if ((err = SSLAllocBuffer(alloc, ctx->peerDHParams.primeLen +
+ ctx->peerDHParams.generatorLen, ctx)) != 0)
+ return err;
+
+ ctx->peerDHParams.prime = alloc.data;
+ memcpy(ctx->peerDHParams.prime, prime, ctx->peerDHParams.primeLen);
+ ctx->peerDHParams.generator = alloc.data + ctx->peerDHParams.primeLen;
+ memcpy(ctx->peerDHParams.generator, generator, ctx->peerDHParams.generatorLen);
+
+ if ((err = SSLAllocBuffer(ctx->dhPeerPublic,
+ ctx->dhPeerPublic.length, ctx)) != 0)
+ return err;
+
+ memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
+ }
+#elif BSAFE
+ { int rsaErr;
+ unsigned char *publicVal;
+ A_DH_KEY_AGREE_PARAMS params;
+ B_ALGORITHM_METHOD *chooser[] = { &AM_DH_KEY_AGREE, 0 };
+
+ params.prime.len = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ params.prime.data = charPtr;
+ charPtr += params.prime.len;
+ totalLength += params.prime.len;
+ if (message.length < 6 + totalLength)
+ return errSSLProtocol;
+
+ params.base.len = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ params.base.data = charPtr;
+ charPtr += params.base.len;
+ totalLength += params.base.len;
+ if (message.length < 6 + totalLength)
+ return errSSLProtocol;
+
+ ctx->dhPeerPublic.length = SSLDecodeInt(charPtr, 2);
+ if ((err = SSLAllocBuffer(ctx->dhPeerPublic, ctx->dhPeerPublic.length, ctx)) != 0)
+ return err;
+
+ charPtr += 2;
+ publicVal = charPtr;
+ charPtr += ctx->dhPeerPublic.length;
+ totalLength += ctx->dhPeerPublic.length;
+ memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
+ if (message.length != 6 + totalLength)
+ return errSSLProtocol;
+
+ params.exponentBits = 8 * ctx->dhPeerPublic.length - 1;
+
+ if ((rsaErr = B_CreateAlgorithmObject(&ctx->peerDHParams)) != 0)
+ return SSLUnknownErr;
+ if ((rsaErr = B_SetAlgorithmInfo(ctx->peerDHParams, AI_DHKeyAgree, (POINTER)¶ms)) != 0)
+ return SSLUnknownErr;
+ if ((rsaErr = B_KeyAgreeInit(ctx->peerDHParams, (B_KEY_OBJ) 0, chooser, NO_SURR)) != 0)
+ return SSLUnknownErr;
+ }
+#endif
+
+ return noErr;
+}
+
+#endif
+
+OSStatus
+SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
+{ OSStatus err;
+
+ switch (ctx->selectedCipherSpec->keyExchangeMethod)
+ { case SSL_RSA:
+ case SSL_RSA_EXPORT:
+ if ((err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0)
+ return err;
+ break;
+ #if APPLE_DH
+ case SSL_DH_anon:
+ if ((err = SSLDecodeDHanonKeyExchange(keyExchange, ctx)) != 0)
+ return err;
+ break;
+ #endif
+ default:
+ return unimpErr;
+ }
+
+ return noErr;
+}
+
+static OSStatus
+SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer result;
+ UInt32 outputLen, localKeyModulusLen;
+ CSSM_KEY_PTR *key;
+ SSLProtocolVersion version;
+ Boolean useEncryptKey = false;
+ UInt8 *src = NULL;
+
+
+ /* different key names, also need CSP handle */
+ CSSM_CSP_HANDLE cspHand;
+
+ assert(ctx->protocolSide == SSL_ServerSide);
+
+ #if SSL_SERVER_KEYEXCH_HACK
+ /*
+ * the way we work with Netscape.
+ * FIXME - maybe we should *require* an encryptPrivKey in this
+ * situation?
+ */
+ if((ctx->selectedCipherSpec->keyExchangeMethod == SSL_RSA_EXPORT) &&
+ (ctx->encryptPrivKey != NULL)) {
+ useEncryptKey = true;
+ }
+
+ #else /* !SSL_SERVER_KEYEXCH_HACK */
+ /* The "correct" way, I think, which doesn't work with Netscape */
+ if (ctx->encryptPrivKey) {
+ useEncryptKey = true;
+ }
+ #endif /* SSL_SERVER_KEYEXCH_HACK */
+ if (useEncryptKey) {
+ key = &ctx->encryptPrivKey;
+ cspHand = ctx->encryptKeyCsp;
+ }
+ else {
+ key = &ctx->signingPrivKey;
+ cspHand = ctx->signingKeyCsp;
+ }
+
+ localKeyModulusLen = sslKeyLengthInBytes(*key);
+
+ /*
+ * We have to tolerate incoming key exchange msgs with and without the
+ * two-byte "encrypted length" field.
+ */
+ if (keyExchange.length == localKeyModulusLen) {
+ /* no length encoded */
+ src = keyExchange.data;
+ }
+ else if((keyExchange.length == (localKeyModulusLen + 2)) &&
+ (ctx->negProtocolVersion >= TLS_Version_1_0)) {
+ /* TLS only - skip the length bytes */
+ src = keyExchange.data + 2;
+ }
+ else {
+ sslErrorLog("SSLDecodeRSAKeyExchange: length error (exp %u got %u)\n",
+ (unsigned)localKeyModulusLen, (unsigned)keyExchange.length);
+ return errSSLProtocol;
+ }
+ err = SSLAllocBuffer(result, localKeyModulusLen, ctx);
+ if(err != 0) {
+ return err;
+ }
+
+ err = sslRsaDecrypt(ctx,
+ *key,
+ cspHand,
+ src,
+ localKeyModulusLen,
+ result.data,
+ 48,
+ &outputLen);
+ if(err) {
+ goto fail;
+ }
+
+ if (outputLen != 48)
+ {
+ sslErrorLog("SSLDecodeRSAKeyExchange: outputLen error\n");
+ err = errSSLProtocol;
+ goto fail;
+ }
+ result.length = outputLen;
+
+ version = (SSLProtocolVersion)SSLDecodeInt(result.data, 2);
+ /* Modify this check to check against our maximum version with
+ * protocol revisions */
+ if (version > ctx->negProtocolVersion && version < SSL_Version_3_0) {
+ sslErrorLog("SSLDecodeRSAKeyExchange: version error\n");
+ err = errSSLProtocol;
+ goto fail;
+ }
+ if ((err = SSLAllocBuffer(ctx->preMasterSecret,
+ SSL_RSA_PREMASTER_SECRET_SIZE, ctx)) != 0)
+ goto fail;
+ memcpy(ctx->preMasterSecret.data, result.data,
+ SSL_RSA_PREMASTER_SECRET_SIZE);
+
+ err = noErr;
+fail:
+ SSLFreeBuffer(result, ctx);
+ return err;
+}
+
+#if APPLE_DH
+static OSStatus
+SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
+{ OSStatus err;
+ unsigned int publicLen;
+ int rsaResult;
+
+ publicLen = SSLDecodeInt(keyExchange.data, 2);
+
+#if RSAREF
+ if (keyExchange.length != publicLen + 2 ||
+ publicLen != ctx->dhAnonParams.primeLen)
+ return errSSLProtocol;
+
+ if ((err = SSLAllocBuffer(ctx->preMasterSecret, ctx->dhAnonParams.primeLen, ctx)) != 0)
+ return err;
+
+ if ((rsaResult = R_ComputeDHAgreedKey (ctx->preMasterSecret.data, ctx->dhPeerPublic.data,
+ ctx->dhPrivate.data, ctx->dhPrivate.length, &ctx->dhAnonParams)) != 0)
+ { err = SSLUnknownErr;
+ return err;
+ }
+
+#elif BSAFE
+ { unsigned int amount;
+ if (keyExchange.length != publicLen + 2)
+ return errSSLProtocol;
+
+ if ((err = SSLAllocBuffer(ctx->preMasterSecret, 128, ctx)) != 0)
+ return err;
+
+ if ((rsaResult = B_KeyAgreePhase2(ctx->dhAnonParams, ctx->preMasterSecret.data,
+ &amount, 128, keyExchange.data+2, publicLen, NO_SURR)) != 0)
+ return err;
+
+ ctx->preMasterSecret.length = amount;
+ }
+#endif
+
+ return noErr;
+}
+#endif /* APPLE_DH */
+
+OSStatus
+SSLEncodeKeyExchange(SSLRecord &keyExchange, SSLContext *ctx)
+{ OSStatus err;
+
+ assert(ctx->protocolSide == SSL_ClientSide);
+
+ switch (ctx->selectedCipherSpec->keyExchangeMethod)
+ { case SSL_RSA:
+ case SSL_RSA_EXPORT:
+ if ((err = SSLEncodeRSAKeyExchange(keyExchange, ctx)) != 0)
+ return err;
+ break;
+ #if APPLE_DH
+ case SSL_DH_anon:
+ if ((err = SSLEncodeDHanonKeyExchange(keyExchange, ctx)) != 0)
+ return err;
+ break;
+ #endif
+ default:
+ return unimpErr;
+ }
+
+ return noErr;
+}
+
+static OSStatus
+SSLEncodeRSAKeyExchange(SSLRecord &keyExchange, SSLContext *ctx)
+{ OSStatus err;
+ UInt32 outputLen, peerKeyModulusLen;
+ UInt32 bufLen;
+ UInt8 *dst;
+ bool encodeLen = false;
+
+ if ((err = SSLEncodeRSAPremasterSecret(ctx)) != 0)
+ return err;
+
+ keyExchange.contentType = SSL_RecordTypeHandshake;
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ keyExchange.protocolVersion = ctx->negProtocolVersion;
+
+ peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
+ bufLen = peerKeyModulusLen + 4;
+ #if RSA_CLIENT_KEY_ADD_LENGTH
+ if(ctx->negProtocolVersion >= TLS_Version_1_0) {
+ bufLen += 2;
+ encodeLen = true;
+ }
+ #endif
+ if ((err = SSLAllocBuffer(keyExchange.contents,
+ bufLen,ctx)) != 0)
+ {
+ return err;
+ }
+ dst = keyExchange.contents.data + 4;
+ if(encodeLen) {
+ dst += 2;
+ }
+ keyExchange.contents.data[0] = SSL_HdskClientKeyExchange;
+
+ /* this is the record payload length */
+ SSLEncodeInt(keyExchange.contents.data + 1, bufLen - 4, 3);
+ if(encodeLen) {
+ /* the length of the encrypted pre_master_secret */
+ SSLEncodeInt(keyExchange.contents.data + 4,
+ peerKeyModulusLen, 2);
+ }
+ err = sslRsaEncrypt(ctx,
+ ctx->peerPubKey,
+ /* FIXME - maybe this should be ctx->cspHand */
+ ctx->peerPubKeyCsp,
+ ctx->preMasterSecret.data,
+ SSL_RSA_PREMASTER_SECRET_SIZE,
+ dst,
+ peerKeyModulusLen,
+ &outputLen);
+ if(err) {
+ return err;
+ }
+
+ assert(outputLen == encodeLen ?
+ keyExchange.contents.length - 6 :
+ keyExchange.contents.length - 4 );
+
+ return noErr;
+}
+
+#if APPLE_DH
+static OSStatus
+SSLEncodeDHanonKeyExchange(SSLRecord &keyExchange, SSLContext *ctx)
+{ OSStatus err;
+ unsigned int outputLen;
+
+ if ((err = SSLEncodeDHPremasterSecret(ctx)) != 0)
+ return err;
+
+ outputLen = ctx->dhExchangePublic.length + 2;
+
+ keyExchange.contentType = SSL_RecordTypeHandshake;
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ keyExchange.protocolVersion = ctx->negProtocolVersion;
+
+ if ((err = SSLAllocBuffer(keyExchange.contents,outputLen + 4,ctx)) != 0)
+ return err;
+
+ keyExchange.contents.data[0] = SSL_HdskClientKeyExchange;
+ SSLEncodeInt(keyExchange.contents.data+1, ctx->dhExchangePublic.length+2, 3);
+
+ SSLEncodeInt(keyExchange.contents.data+4, ctx->dhExchangePublic.length, 2);
+ memcpy(keyExchange.contents.data+6, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
+
+ return noErr;
+}
+#endif
+
+OSStatus
+SSLEncodeRSAPremasterSecret(SSLContext *ctx)
+{ SSLBuffer randData;
+ OSStatus err;
+
+ if ((err = SSLAllocBuffer(ctx->preMasterSecret,
+ SSL_RSA_PREMASTER_SECRET_SIZE, ctx)) != 0)
+ return err;
+
+ assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+ (ctx->negProtocolVersion == TLS_Version_1_0));
+ SSLEncodeInt(ctx->preMasterSecret.data, ctx->maxProtocolVersion, 2);
+ randData.data = ctx->preMasterSecret.data+2;
+ randData.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
+ if ((err = sslRand(ctx, &randData)) != 0)
+ return err;
+ return noErr;
+}
+
+#if APPLE_DH
+
+OSStatus
+SSLEncodeDHPremasterSecret(SSLContext *ctx)
+{
+ #if !APPLE_DH
+ return unimpErr;
+ #else
+
+ OSStatus err;
+ int rsaResult;
+ SSLRandomCtx rsaRandom;
+
+/* Given the server's Diffie-Hellman parameters, prepare a public & private value,
+ * then use the public value provided by the server and our private value to
+ * generate a shared key (the premaster secret). Save our public value in
+ * ctx->dhExchangePublic to send to the server so it can calculate the matching
+ * key on its end
+ */
+ if ((err = ReadyRandom(&rsaRandom, ctx)) != 0)
+ return err;
+
+#if RSAREF
+ { privateValue.data = 0;
+
+ if ((err = SSLAllocBuffer(ctx->dhExchangePublic, ctx->peerDHParams.primeLen, ctx)) != 0)
+ goto fail;
+ if ((err = SSLAllocBuffer(privateValue, ctx->dhExchangePublic.length - 16, ctx)) != 0)
+ goto fail;
+
+ if ((rsaResult = R_SetupDHAgreement(ctx->dhExchangePublic.data, privateValue.data,
+ privateValue.length, &ctx->peerDHParams, &rsaRandom)) != 0)
+ { err = SSLUnknownErr;
+ goto fail;
+ }
+
+ if ((err = SSLAllocBuffer(ctx->preMasterSecret, ctx->peerDHParams.primeLen, ctx)) != 0)
+ goto fail;
+
+ if ((rsaResult = R_ComputeDHAgreedKey (ctx->preMasterSecret.data, ctx->dhPeerPublic.data,
+ privateValue.data, privateValue.length, &ctx->peerDHParams)) != 0)
+ { err = SSLUnknownErr;
+ goto fail;
+ }
+ }
+#elif BSAFE
+ { unsigned int outputLen;
+
+ if ((err = SSLAllocBuffer(ctx->dhExchangePublic, 128, ctx)) != 0)
+ goto fail;
+ if ((rsaResult = B_KeyAgreePhase1(ctx->peerDHParams, ctx->dhExchangePublic.data,
+ &outputLen, 128, rsaRandom, NO_SURR)) != 0)
+ { err = SSLUnknownErr;
+ goto fail;
+ }
+ ctx->dhExchangePublic.length = outputLen;
+ if ((err = SSLAllocBuffer(ctx->preMasterSecret, 128, ctx)) != 0)
+ goto fail;
+ if ((rsaResult = B_KeyAgreePhase2(ctx->peerDHParams, ctx->preMasterSecret.data,
+ &outputLen, 128, ctx->dhPeerPublic.data, ctx->dhPeerPublic.length,
+ NO_SURR)) != 0)
+ { err = SSLUnknownErr;
+ goto fail;
+ }
+ ctx->preMasterSecret.length = outputLen;
+ }
+ #endif
+
+ err = noErr;
+fail:
+#if RSAREF
+ SSLFreeBuffer(privateValue, ctx);
+ R_RandomFinal(&rsaRandom);
+#elif BSAFE
+ B_DestroyAlgorithmObject(&rsaRandom);
+#endif
+ return err;
+ #endif
+}
+
+#endif /* APPLE_DH */
+
+OSStatus
+SSLInitPendingCiphers(SSLContext *ctx)
+{ OSStatus err;
+ SSLBuffer key;
+ UInt8 *keyDataProgress, *keyPtr, *ivPtr;
+ int keyDataLen;
+ CipherContext *serverPending, *clientPending;
+
+ key.data = 0;
+
+ ctx->readPending.macRef = ctx->selectedCipherSpec->macAlgorithm;
+ ctx->writePending.macRef = ctx->selectedCipherSpec->macAlgorithm;
+ ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
+ ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
+ ctx->readPending.sequenceNum.high = ctx->readPending.sequenceNum.low = 0;
+ ctx->writePending.sequenceNum.high = ctx->writePending.sequenceNum.low = 0;
+
+ keyDataLen = ctx->selectedCipherSpec->macAlgorithm->hash->digestSize +
+ ctx->selectedCipherSpec->cipher->secretKeySize;
+ if (ctx->selectedCipherSpec->isExportable == NotExportable)
+ keyDataLen += ctx->selectedCipherSpec->cipher->ivSize;
+ keyDataLen *= 2; /* two of everything */
+
+ if ((err = SSLAllocBuffer(key, keyDataLen, ctx)) != 0)
+ return err;
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->generateKeyMaterial(key, ctx)) != 0)
+ goto fail;
+
+ if (ctx->protocolSide == SSL_ServerSide)
+ { serverPending = &ctx->writePending;
+ clientPending = &ctx->readPending;
+ }
+ else
+ { serverPending = &ctx->readPending;
+ clientPending = &ctx->writePending;
+ }
+
+ keyDataProgress = key.data;
+ memcpy(clientPending->macSecret, keyDataProgress,
+ ctx->selectedCipherSpec->macAlgorithm->hash->digestSize);
+ keyDataProgress += ctx->selectedCipherSpec->macAlgorithm->hash->digestSize;
+ memcpy(serverPending->macSecret, keyDataProgress,
+ ctx->selectedCipherSpec->macAlgorithm->hash->digestSize);
+ keyDataProgress += ctx->selectedCipherSpec->macAlgorithm->hash->digestSize;
+
+ /* init the reusable-per-record MAC contexts */
+ err = ctx->sslTslCalls->initMac(clientPending, ctx);
+ if(err) {
+ goto fail;
+ }
+ err = ctx->sslTslCalls->initMac(serverPending, ctx);
+ if(err) {
+ goto fail;
+ }
+
+ if (ctx->selectedCipherSpec->isExportable == NotExportable)
+ { keyPtr = keyDataProgress;
+ keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
+ /* Skip server write key to get to IV */
+ ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->secretKeySize;
+ if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
+ clientPending, ctx)) != 0)
+ goto fail;
+ keyPtr = keyDataProgress;
+ keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
+ /* Skip client write IV to get to server write IV */
+ ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->ivSize;
+ if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
+ serverPending, ctx)) != 0)
+ goto fail;
+ }
+ else {
+ UInt8 clientExportKey[16], serverExportKey[16],
+ clientExportIV[16], serverExportIV[16];
+ SSLBuffer clientWrite, serverWrite;
+ SSLBuffer finalClientWrite, finalServerWrite;
+ SSLBuffer finalClientIV, finalServerIV;
+
+ assert(ctx->selectedCipherSpec->cipher->keySize <= 16);
+ assert(ctx->selectedCipherSpec->cipher->ivSize <= 16);
+
+ /* Inputs to generateExportKeyAndIv are clientRandom, serverRandom,
+ * clientWriteKey, serverWriteKey. The first two are already present
+ * in ctx.
+ * Outputs are a key and IV for each of {server, client}.
+ */
+ clientWrite.data = keyDataProgress;
+ clientWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
+ serverWrite.data = keyDataProgress + clientWrite.length;
+ serverWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
+ finalClientWrite.data = clientExportKey;
+ finalServerWrite.data = serverExportKey;
+ finalClientIV.data = clientExportIV;
+ finalServerIV.data = serverExportIV;
+ finalClientWrite.length = 16;
+ finalServerWrite.length = 16;
+ /* these can be zero */
+ finalClientIV.length = ctx->selectedCipherSpec->cipher->ivSize;
+ finalServerIV.length = ctx->selectedCipherSpec->cipher->ivSize;
+
+ assert(ctx->sslTslCalls != NULL);
+ err = ctx->sslTslCalls->generateExportKeyAndIv(ctx, clientWrite, serverWrite,
+ finalClientWrite, finalServerWrite, finalClientIV, finalServerIV);
+ if(err) {
+ goto fail;
+ }
+ if ((err = ctx->selectedCipherSpec->cipher->initialize(clientExportKey,
+ clientExportIV, clientPending, ctx)) != 0)
+ goto fail;
+ if ((err = ctx->selectedCipherSpec->cipher->initialize(serverExportKey,
+ serverExportIV, serverPending, ctx)) != 0)
+ goto fail;
+ }
+
+ /* Ciphers are ready for use */
+ ctx->writePending.ready = 1;
+ ctx->readPending.ready = 1;
+
+ /* Ciphers get swapped by sending or receiving a change cipher spec message */
+
+ err = noErr;
+fail:
+ SSLFreeBuffer(key, ctx);
+ return err;
+}
+
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslKeychain.c
-
- Contains: Apple Keychain routines
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-
-#include "ssl.h"
-#include "sslctx.h"
-#include "sslalloc.h"
-#include "appleCdsa.h"
-#include "appleGlue.h"
-#include "sslerrs.h"
-#include "sslDebug.h"
-#include "sslKeychain.h"
-#include "sslutil.h"
-#include <string.h>
-#include <assert.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-#include <Security/cssm.h>
-/* these are to be replaced by Security/Security.h */
-#include <Security/SecCertificate.h>
-#include <Security/SecKeychainItem.h>
-#include <Security/SecKeychain.h>
-#include <Security/SecIdentity.h>
-#include <Security/SecIdentitySearch.h>
-#include <Security/SecKey.h>
-
-#if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
-static OSStatus
-addCertData(
- SSLContext *ctx,
- KCItemRef kcItem,
- CSSM_DATA_PTR certData,
- Boolean *goodCert); /* RETURNED */
-#endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
-
-#if (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
-
-#if ST_FAKE_KEYCHAIN
-/*
- * Routines which will be replaced by SecKeychainAPI.
- */
-
-/*
- * Given a DLDB, find the first private key in the DB. It's the application's
- * responsibility to ensure that there is only one private key. The returned
- * PrintName attribute will be used to search for an associated cert using
- * TBD.
- *
- * Caller must free returned key and PrintName.
- */
-static OSStatus
-findPrivateKeyInDb(
- SSLContext *ctx,
- CSSM_DL_DB_HANDLE dlDbHand,
- CSSM_KEY_PTR *privKey, // mallocd and RETURNED
- CSSM_DATA *printName) // referent mallocd and RETURNED
-{
- CSSM_QUERY query;
- CSSM_DB_UNIQUE_RECORD_PTR record = NULL;
- CSSM_RETURN crtn;
- CSSM_HANDLE resultHand;
- CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs;
- CSSM_DB_ATTRIBUTE_DATA theAttr;
- CSSM_DB_ATTRIBUTE_INFO_PTR attrInfo = &theAttr.Info;
- CSSM_DATA theData = {0, NULL};
-
- /* search by record type, no predicates (though we do want the PrintName
- * attr returned). */
- query.RecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
- query.Conjunctive = CSSM_DB_NONE;
- query.NumSelectionPredicates = 0;
- query.SelectionPredicate = NULL;
- query.QueryLimits.TimeLimit = 0; // FIXME - meaningful?
- query.QueryLimits.SizeLimit = 1; // FIXME - meaningful?
- query.QueryFlags = CSSM_QUERY_RETURN_DATA; // FIXME - used?
-
- recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
- recordAttrs.SemanticInformation = 0;
- recordAttrs.NumberOfAttributes = 1;
- recordAttrs.AttributeData = &theAttr;
-
- attrInfo->AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
- attrInfo->Label.AttributeName = "PrintName";
- attrInfo->AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB;
-
- theAttr.NumberOfValues = 1;
- theAttr.Value = NULL;
-
- crtn = CSSM_DL_DataGetFirst(dlDbHand,
- &query,
- &resultHand,
- &recordAttrs,
- &theData,
- &record);
- /* terminate query only on success */
- if(crtn == CSSM_OK) {
- CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
- *privKey = (CSSM_KEY_PTR)theData.Data;
- /*
- * Both the struct and the referent are mallocd by DL. Give our
- * caller the referent; free the struct.
- */
- *printName = *theAttr.Value;
- stAppFree(theAttr.Value, NULL);
- return noErr;
- }
- else {
- stPrintCdsaError("CSSM_DL_DataGetFirst", crtn);
- errorLog0("findCertInDb: cert not found\n");
- return errSSLBadCert;
- }
-}
-
-static OSStatus
-findCertInDb(
- SSLContext *ctx,
- CSSM_DL_DB_HANDLE dlDbHand,
- const CSSM_DATA *printName, // obtained from findPrivateKeyInDb
- CSSM_DATA *certData) // referent mallocd and RETURNED
-{
- CSSM_QUERY query;
- CSSM_SELECTION_PREDICATE predicate;
- CSSM_DB_UNIQUE_RECORD_PTR record = NULL;
- CSSM_RETURN crtn;
- CSSM_HANDLE resultHand;
-
- predicate.DbOperator = CSSM_DB_EQUAL;
- predicate.Attribute.Info.AttributeNameFormat =
- CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
- predicate.Attribute.Info.Label.AttributeName = "PrintName";
- predicate.Attribute.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB;
- /* hope this const_cast is OK */
- predicate.Attribute.Value = (CSSM_DATA_PTR)printName;
- predicate.Attribute.NumberOfValues = 1;
-
- query.RecordType = CSSM_DL_DB_RECORD_X509_CERTIFICATE;
- query.Conjunctive = CSSM_DB_NONE;
- query.NumSelectionPredicates = 1;
- query.SelectionPredicate = &predicate;
- query.QueryLimits.TimeLimit = 0; // FIXME - meaningful?
- query.QueryLimits.SizeLimit = 1; // FIXME - meaningful?
- query.QueryFlags = 0; // FIXME - used?
-
- crtn = CSSM_DL_DataGetFirst(dlDbHand,
- &query,
- &resultHand,
- NULL, // no attrs returned
- certData,
- &record);
- /* terminate query only on success */
- if(crtn == CSSM_OK) {
- CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
- return noErr;
- }
- else {
- stPrintCdsaError("CSSM_DL_DataGetFirst", crtn);
- errorLog0("findCertInDb: cert not found\n");
- return errSSLBadCert;
- }
-}
-
-
-#endif /* ST_FAKE_KEYCHAIN */
-/*
- * Given an array of certs (as SecIdentityRefs, specified by caller
- * in SSLSetCertificate or SSLSetEncryptionCertificate) and a
- * destination SSLCertificate:
- *
- * -- free destCerts if we have any
- * -- Get raw cert data, convert to array of SSLCertificates in *destCert
- * -- validate cert chain
- * -- get pub, priv keys from certRef[0], store in *pubKey, *privKey
- */
-
-#if ST_FAKE_KEYCHAIN
-/*
- * In this incarnation, the certs array actually holds one pointer to a
- * CSSM_DL_DB_HANDLE. In that DL/DB is exactly one private key; that's
- * our privKey. We use the KeyLabel of that key to look up a cert with
- * the same label. We get the public key from the cert. Other certs and
- * public keys in the DL/DB are ignored.
- */
-OSStatus
-parseIncomingCerts(
- SSLContext *ctx,
- CFArrayRef certs,
- SSLCertificate **destCert, /* &ctx->{localCert,encryptCert} */
- CSSM_KEY_PTR *pubKey, /* &ctx->signingPubKey, etc. */
- CSSM_KEY_PTR *privKey, /* &ctx->signingPrivKey, etc. */
- CSSM_CSP_HANDLE *cspHand /* &ctx->signingKeyCsp, etc. */
- #if ST_KC_KEYS_NEED_REF
- ,
- SecKeychainRef *privKeyRef) /* &ctx->signingKeyRef, etc. */
- #else
- )
- #endif /* ST_KC_KEYS_NEED_REF */
-{
- CSSM_DL_DB_HANDLE_PTR dlDbHand = NULL;
- CFIndex numCerts;
- CSSM_KEY_PTR lookupPriv = NULL;
- CSSM_DATA lookupLabel = {0, NULL};
- CSSM_DATA lookupCert = {0, NULL};
- OSStatus ortn;
- SSLCertificate *certChain = NULL;
- SSLCertificate *thisSslCert;
- SSLErr srtn;
- CSSM_CSP_HANDLE dummyCsp;
-
- assert(ctx != NULL);
- assert(destCert != NULL); /* though its referent may be NULL */
- assert(pubKey != NULL);
- assert(privKey != NULL);
- assert(cspHand != NULL);
-
- sslDeleteCertificateChain(*destCert, ctx);
- *destCert = NULL;
- *pubKey = NULL;
- *privKey = NULL;
- *cspHand = 0;
-
- if(certs == NULL) {
- dprintf0("parseIncomingCerts: NULL incoming cert (DLDB) array\n");
- return errSSLBadCert;
- }
- numCerts = CFArrayGetCount(certs);
- if(numCerts != 1) {
- dprintf0("parseIncomingCerts: empty incoming cert (DLDB) array\n");
- return errSSLBadCert;
- }
- dlDbHand = (CSSM_DL_DB_HANDLE_PTR)CFArrayGetValueAtIndex(certs, 0);
- if(dlDbHand == NULL) {
- errorLog0("parseIncomingCerts: bad cert (DLDB) array\n");
- return paramErr;
- }
-
- /* get private key - app has to ensure there is only one (for now) */
- ortn = findPrivateKeyInDb(ctx, *dlDbHand, &lookupPriv, &lookupLabel);
- if(ortn) {
- errorLog0("parseIncomingCerts: no private key\n");
- return ortn;
- }
- assert(lookupPriv->KeyHeader.BlobType == CSSM_KEYBLOB_REFERENCE);
- assert(lookupPriv->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY);
-
- /* get associated cert */
- ortn = findCertInDb(ctx, *dlDbHand, &lookupLabel, &lookupCert);
- if(ortn) {
- errorLog0("parseIncomingCerts: no cert\n");
- return ortn;
- }
- sslFree(lookupLabel.Data);
- assert(lookupCert.Length > 100); // quickie check
-
- /*
- * Cook up an SSLCertificate and its associated SSLBuffer.
- */
- thisSslCert = sslMalloc(sizeof(SSLCertificate));
- if(thisSslCert == NULL) {
- return memFullErr;
- }
- if(SSLAllocBuffer(&thisSslCert->derCert, lookupCert.Length, &ctx->sysCtx)) {
- return memFullErr;
- }
-
- /* copy cert data mallocd by DL */
- memmove(thisSslCert->derCert.data, lookupCert.Data, lookupCert.Length);
- sslFree(lookupCert.Data);
-
- /* enqueue onto head of cert chain */
- thisSslCert->next = certChain;
- certChain = thisSslCert;
-
- /* TBD - we might fetch other certs from CFArrayRef certs here and enqueue
- * them on certChain */
-
- /* now the public key of the first cert, from CL */
- srtn = sslPubKeyFromCert(ctx,
- &certChain->derCert,
- pubKey,
- &dummyCsp);
- if(srtn) {
- errorLog1("sslPubKeyFromCert returned %d\n", srtn);
- ortn = sslErrToOsStatus(srtn);
- goto errOut;
- }
- assert((*pubKey)->KeyHeader.BlobType == CSSM_KEYBLOB_RAW);
- assert((*pubKey)->KeyHeader.KeyClass == CSSM_KEYCLASS_PUBLIC_KEY);
-
- /*
- * NOTE: as of 2/7/02, the size of the extracted public key will NOT
- * always equal the size of the private key. Non-byte-aligned key sizes
- * for RSA keys result in the extracted public key's size to be rounded
- * UP to the next byte boundary.
- */
- assert((*pubKey)->KeyHeader.LogicalKeySizeInBits ==
- ((lookupPriv->KeyHeader.LogicalKeySizeInBits + 7) & ~7));
-
- /* SUCCESS */
- *destCert = certChain;
- *privKey = lookupPriv;
-
- /* we get this at context create time */
- assert(ctx->cspDlHand != 0);
- *cspHand = ctx->cspDlHand;
- *privKeyRef = NULL; // not used
- return noErr;
-
-errOut:
- /* free certChain, everything in it, other vars, return ortn */
- sslDeleteCertificateChain(certChain, ctx);
- if(lookupPriv != NULL) {
- sslFreeKey(ctx->cspDlHand, &lookupPriv, NULL);
- }
- return ortn;
-}
-
-#else /* !ST_FAKE_KEYCHAIN */
-
-/* Convert a SecCertificateRef to an SSLCertificate * */
-static OSStatus secCertToSslCert(
- SSLContext *ctx,
- SecCertificateRef certRef,
- SSLCertificate **sslCert)
-{
- CSSM_DATA certData; // struct is transient, referent owned by
- // Sec layer
- OSStatus ortn;
- SSLCertificate *thisSslCert = NULL;
-
- ortn = SecCertificateGetData(certRef, &certData);
- if(ortn) {
- errorLog1("SecCertificateGetData() returned %d\n", (int)ortn);
- return ortn;
- }
-
- thisSslCert = sslMalloc(sizeof(SSLCertificate));
- if(thisSslCert == NULL) {
- return memFullErr;
- }
- if(SSLAllocBuffer(&thisSslCert->derCert, certData.Length,
- &ctx->sysCtx)) {
- return memFullErr;
- }
- memcpy(thisSslCert->derCert.data, certData.Data, certData.Length);
- thisSslCert->derCert.length = certData.Length;
- *sslCert = thisSslCert;
- return noErr;
-}
-
-OSStatus
-parseIncomingCerts(
- SSLContext *ctx,
- CFArrayRef certs,
- SSLCertificate **destCert, /* &ctx->{localCert,encryptCert} */
- CSSM_KEY_PTR *pubKey, /* &ctx->signingPubKey, etc. */
- CSSM_KEY_PTR *privKey, /* &ctx->signingPrivKey, etc. */
- CSSM_CSP_HANDLE *cspHand /* &ctx->signingKeyCsp, etc. */
- #if ST_KC_KEYS_NEED_REF
- ,
- SecKeychainRef *privKeyRef) /* &ctx->signingKeyRef, etc. */
- #else
- )
- #endif /* ST_KC_KEYS_NEED_REF */
-{
- CFIndex numCerts;
- CFIndex cert;
- SSLCertificate *certChain = NULL;
- SSLCertificate *thisSslCert;
- SecKeychainRef kcRef;
- OSStatus ortn;
- SSLErr srtn;
- SecIdentityRef identity;
- SecCertificateRef certRef;
- SecKeyRef keyRef;
- CSSM_DATA certData;
- CSSM_CL_HANDLE clHand; // carefully derive from a SecCertificateRef
- CSSM_RETURN crtn;
-
- CASSERT(ctx != NULL);
- CASSERT(destCert != NULL); /* though its referent may be NULL */
- CASSERT(pubKey != NULL);
- CASSERT(privKey != NULL);
- CASSERT(cspHand != NULL);
-
- sslDeleteCertificateChain(*destCert, ctx);
- *destCert = NULL;
- *pubKey = NULL;
- *privKey = NULL;
- *cspHand = 0;
-
- if(certs == NULL) {
- dprintf0("parseIncomingCerts: NULL incoming cert array\n");
- return errSSLBadCert;
- }
- numCerts = CFArrayGetCount(certs);
- if(numCerts == 0) {
- dprintf0("parseIncomingCerts: empty incoming cert array\n");
- return errSSLBadCert;
- }
-
- /*
- * Certs[0] is an SecIdentityRef from which we extract subject cert,
- * privKey, pubKey, and cspHand.
- *
- * 1. ensure the first element is a SecIdentityRef.
- */
- identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
- if(identity == NULL) {
- errorLog0("parseIncomingCerts: bad cert array (1)\n");
- return paramErr;
- }
- if(CFGetTypeID(identity) != SecIdentityGetTypeID()) {
- errorLog0("parseIncomingCerts: bad cert array (2)\n");
- return paramErr;
- }
-
- /*
- * 2. Extract cert, keys, CSP handle and convert to local format.
- */
- ortn = SecIdentityCopyCertificate(identity, &certRef);
- if(ortn) {
- errorLog0("parseIncomingCerts: bad cert array (3)\n");
- return ortn;
- }
- ortn = secCertToSslCert(ctx, certRef, &thisSslCert);
- if(ortn) {
- errorLog0("parseIncomingCerts: bad cert array (4)\n");
- return ortn;
- }
- /* enqueue onto head of cert chain */
- thisSslCert->next = certChain;
- certChain = thisSslCert;
-
- /* fetch private key from identity */
- ortn = SecIdentityCopyPrivateKey(identity, &keyRef);
- if(ortn) {
- errorLog1("parseIncomingCerts: SecIdentityCopyPrivateKey err %d\n",
- (int)ortn);
- return ortn;
- }
- ortn = SecKeyGetCSSMKey(keyRef, (const CSSM_KEY **)privKey);
- if(ortn) {
- errorLog1("parseIncomingCerts: SecKeyGetCSSMKey err %d\n",
- (int)ortn);
- return ortn;
- }
- /* FIXME = release keyRef? */
-
- /* obtain public key from cert */
- ortn = SecCertificateGetCLHandle(certRef, &clHand);
- if(ortn) {
- errorLog1("parseIncomingCerts: SecCertificateGetCLHandle err %d\n",
- (int)ortn);
- return ortn;
- }
- certData.Data = thisSslCert->derCert.data;
- certData.Length = thisSslCert->derCert.length;
- crtn = CSSM_CL_CertGetKeyInfo(clHand, &certData, pubKey);
- if(crtn) {
- errorLog0("parseIncomingCerts: CSSM_CL_CertGetKeyInfo err\n");
- return (OSStatus)crtn;
- }
-
- #if ST_FAKE_GET_CSPDL_HANDLE
- /* we get this at context create time until SecKeychainGetCSPHandle
- * is working */
- assert(ctx->cspDlHand != 0);
- *cspHand = ctx->cspDlHand;
- #else /* ST_FAKE_GET_CSPDL_HANDLE */
- /* obtain keychain from key, CSP handle from keychain */
- ortn = SecKeychainItemCopyKeychain((SecKeychainItemRef)keyRef, &kcRef);
- if(ortn) {
- errorLog1("parseIncomingCerts: SecKeychainItemCopyKeychain err %d\n",
- (int)ortn);
- return ortn;
- }
- ortn = SecKeychainGetCSPHandle(kcRef, cspHand);
- if(ortn) {
- errorLog1("parseIncomingCerts: SecKeychainGetCSPHandle err %d\n",
- (int)ortn);
- return ortn;
- }
- #endif /* ST_FAKE_GET_CSPDL_HANDLE */
-
- /* OK, that's the subject cert. Fetch optional remaining certs. */
- /*
- * Convert: CFArray of SecCertificateRefs --> chain of SSLCertificates.
- * Incoming certs have root last; SSLCertificate chain has root
- * first.
- */
- for(cert=1; cert<numCerts; cert++) {
- certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certs, cert);
- if(certRef == NULL) {
- errorLog0("parseIncomingCerts: bad cert array (5)\n");
- return paramErr;
- }
- if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) {
- errorLog0("parseIncomingCerts: bad cert array (6)\n");
- return paramErr;
- }
-
- /* Extract cert, convert to local format.
- */
- ortn = secCertToSslCert(ctx, certRef, &thisSslCert);
- if(ortn) {
- errorLog0("parseIncomingCerts: bad cert array (7)\n");
- return ortn;
- }
- /* enqueue onto head of cert chain */
- thisSslCert->next = certChain;
- certChain = thisSslCert;
- }
-
- /* validate the whole mess */
- srtn = sslVerifyCertChain(ctx, certChain);
- if(srtn) {
- ortn = sslErrToOsStatus(srtn);
- goto errOut;
- }
-
- /* SUCCESS */
- *destCert = certChain;
- return noErr;
-
-errOut:
- /* free certChain, everything in it, other vars, return ortn */
- sslDeleteCertificateChain(certChain, ctx);
- /* FIXME - anything else? */
- return ortn;
-}
-#endif /* ST_FAKE_KEYCHAIN */
-#endif /* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
-
-/*
- * Add Apple built-in root certs to ctx->trustedCerts.
- */
-OSStatus addBuiltInCerts (SSLContextRef ctx)
-{
- #if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
- OSStatus ortn;
- KCRef kc = nil;
-
- ortn = KCDispatch(kKCGetRootCertificateKeychain, &kc);
- if(ortn) {
- errorLog1("KCDispatch(kKCGetRootCertificateKeychain) returned %d\n",
- ortn);
- return ortn;
- }
- return parseTrustedKeychain(ctx, kc);
- #else
- /* nothing for now */
- return noErr;
- #endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
-}
-
-#if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
-
-/*
- * Given an open Keychain:
- * -- Get raw cert data, add to array of CSSM_DATAs in
- * ctx->trustedCerts
- * -- verify that each of these is a valid (self-verifying)
- * root cert
- * -- add each subject name to acceptableDNList
- */
-OSStatus
-parseTrustedKeychain (SSLContextRef ctx,
- KCRef keyChainRef)
-{
- CFMutableArrayRef kcCerts = NULL; /* all certs in one keychain */
- uint32 numGoodCerts = 0; /* # of good root certs */
- CSSM_DATA_PTR certData = NULL; /* array of CSSM_DATAs */
- CFIndex certDex; /* index into kcCerts */
- CFIndex certsPerKc; /* # of certs in this KC */
- OSStatus ortn;
- KCItemRef kcItem; /* one cert */
- Boolean goodCert;
-
- CASSERT(ctx != NULL);
- if(keyChainRef == NULL) {
- return paramErr;
- }
-
- ortn = KCFindX509Certificates(keyChainRef,
- NULL, // name, XXX
- NULL, // emailAddress, XXX
- kCertSearchAny, // options
- &kcCerts); // results
- switch(ortn) {
- case noErr:
- break; // proceed
- case errKCItemNotFound:
- return noErr; // no certs; done
- default:
- errorLog1("parseTrustedKeychains: KCFindX509Certificates returned %d\n",
- ortn);
- return ortn;
- }
- if(kcCerts == NULL) {
- dprintf0("parseTrustedKeychains: no certs in KC\n");
- return noErr;
- }
-
- /* Note kcCerts must be released on any exit, successful or
- * otherwise. */
-
- certsPerKc = CFArrayGetCount(kcCerts);
-
- /*
- * This array gets allocd locally; we'll add it to
- * ctx->trustedCerts when we're done.
- */
- certData = sslMalloc(certsPerKc * sizeof(CSSM_DATA));
- if(certData == NULL) {
- ortn = memFullErr;
- goto errOut;
- }
- memset(certData, 0, certsPerKc * sizeof(CSSM_DATA));
-
- /*
- * Build up local certData one root cert at a time.
- * Some certs might not pass muster, hence the numGoodCerts
- * which may or may not increment each time thru.
- */
- for(certDex=0; certDex<certsPerKc; certDex++) {
- kcItem = (KCItemRef)CFArrayGetValueAtIndex(kcCerts, certDex);
- if(kcItem == NULL) {
- errorLog0("parseTrustedKeychains: CF error 1\n");
- ortn = errSSLInternal;
- goto errOut;
- }
- if(!KCIsRootCertificate(kcItem)) {
- /* not root, OK, skip to next cert */
- dprintf1("parseTrustedKeychains: cert %d NOT ROOT\n", certDex);
- continue;
- }
- ortn = addCertData(ctx,
- kcItem,
- &certData[numGoodCerts],
- &goodCert);
- if(ortn) {
- goto errOut;
- }
- if(goodCert) {
- /* added valid root to certData */
- numGoodCerts++;
- }
- } /* for each cert in kcCerts */
-
- #if SSL_DEBUG
- verifyTrustedRoots(ctx, certData, numGoodCerts);
- #endif
-
- /* Realloc ctx->trustedCerts, add new root certs */
- ctx->trustedCerts = sslRealloc(ctx->trustedCerts,
- ctx->numTrustedCerts * sizeof(CSSM_DATA),
- (ctx->numTrustedCerts + numGoodCerts) * sizeof(CSSM_DATA));
- if(ctx->trustedCerts == NULL) {
- ortn = memFullErr;
- goto errOut;
- }
- for(certDex=0; certDex<numGoodCerts; certDex++) {
- ctx->trustedCerts[ctx->numTrustedCerts + certDex] = certData[certDex];
- }
- ctx->numTrustedCerts += numGoodCerts;
- ortn = noErr;
-
- #if SSL_DEBUG
- verifyTrustedRoots(ctx, ctx->trustedCerts, ctx->numTrustedCerts);
- #endif
-
-errOut:
- sslFree(certData);
- if(kcCerts != NULL) {
- CFRelease(kcCerts);
- }
- return ortn;
-}
-
-/*
- * Given a (supposedly) root cert as a KCItemRef:
- * -- verify that the cert self-verifies
- * -- add its DER-encoded data *certData.
- * -- Add its subjectName to acceptableDNList.
- * -- If all is well, return True in *goodCert.
- *
- * The actual CSSM_DATA.Data is mallocd via CSSM_Malloc.
- */
-static OSStatus
-addCertData(
- SSLContext *ctx,
- KCItemRef kcItem,
- CSSM_DATA_PTR certData,
- Boolean *goodCert) /* RETURNED */
-{
- UInt32 certSize;
- OSStatus ortn;
- SSLErr srtn;
- CSSM_BOOL subjectExpired;
- CSSM_DATA_PTR dnData;
-
- CASSERT(ctx != NULL);
- CASSERT(certData != NULL);
- CASSERT(kcItem != NULL);
- CASSERT(goodCert != NULL);
-
- *goodCert = false;
-
- /* how big is the cert? */
- ortn = KCGetData (kcItem, 0, NULL, &certSize);
- if(ortn != noErr) {
- errorLog1("addCertData: KCGetData(1) returned %d\n", ortn);
- return ortn;
- }
-
- /* Allocate the buffer. */
- srtn = stSetUpCssmData(certData, certSize);
- if(srtn) {
- return sslErrToOsStatus(srtn);
- }
-
- /* Get the data. */
- ortn = KCGetData (kcItem, certSize, certData->Data, &certSize);
- if(ortn) {
- errorLog1("addCertData: KCGetData(2) returned %d\n", ortn);
- stFreeCssmData(certData, CSSM_FALSE);
- return ortn;
- }
-
- /*
- * Do actual cert verify, which
- * KCIsRootCertificate does not do. A failure isn't
- * fatal; we just don't add the cert to the array in
- * that case.
- *
- * FIXME - we assume here that our common cspHand can
- * do this cert verify; if not, we have some API work to
- * do (to let the caller specify which CSP to use with
- * trusted certs).
- */
- if(!sslVerifyCert(ctx,
- certData,
- certData,
- ctx->cspHand,
- &subjectExpired)) {
- dprintf0("addCertData: cert does not self-verify!\n");
- stFreeCssmData(certData, CSSM_FALSE);
- return noErr;
- }
-
- /* Add this cert's subject name to (poss. existing) acceptableDNList */
- dnData = sslGetCertSubjectName(ctx, certData);
- if(dnData) {
- DNListElem *dn = sslMalloc(sizeof(DNListElem));
- if(dn == NULL) {
- return memFullErr;
- }
- dn->next = ctx->acceptableDNList;
- ctx->acceptableDNList = dn;
-
- /* move actual data to dn; free the CSSM_DATA struct (must be
- * via CSSM_Free()!) */
- CSSM_TO_SSLBUF(dnData, &dn->derDN);
- sslFree(dnData);
- }
-
- *goodCert = true;
- return noErr;
-}
-
-/*
- * Given a newly encountered root cert (obtained from a peer's cert chain),
- * add it to newRootCertKc if the user so allows, and if so, add it to
- * trustedCerts.
- */
-SSLErr
-sslAddNewRoot(
- SSLContext *ctx,
- const CSSM_DATA_PTR rootCert)
-{
- KCRef defaultKc;
- Boolean bDefaultKcExists;
- KCItemRef certRef = NULL;
- OSStatus ortn;
- CSSM_DATA_PTR newTrustee;
- SSLErr serr;
-
- CASSERT(ctx != NULL);
- CASSERT(rootCert != NULL);
- CASSERT(ctx->newRootCertKc != NULL); /* caller verifies this */
-
- /*
- * Get default KC, temporarily set new default.
- */
- ortn = KCGetDefaultKeychain(&defaultKc);
- if(ortn) {
- bDefaultKcExists = false;
- }
- else {
- bDefaultKcExists = true;
- }
- ortn = KCSetDefaultKeychain(ctx->newRootCertKc);
- if(ortn) {
- errorLog1("sslAddNewRoot: KCSetDefaultKeychain returned %d\n", ortn);
- return SSLUnknownRootCert;
- }
-
- /*
- * Add cert to newRootCertKc. This may well fail due to user
- * interaction ("Do you want to add this root cert...?").
- */
- ortn = KCAddX509Certificate(rootCert->Data, rootCert->Length, &certRef);
-
- /* restore default KC in any case */
- if(bDefaultKcExists) {
- KCSetDefaultKeychain(defaultKc);
- }
- if(ortn) {
- dprintf1("sslAddNewRoot: KCAddX509Certificate returned %d\n", ortn);
- return SSLUnknownRootCert;
- }
-
- /*
- * OK, user accepted new root. Now add to our private stash of
- * trusted roots. Realloc the whole pile...
- */
- ctx->trustedCerts = (CSSM_DATA_PTR)sslRealloc(ctx->trustedCerts,
- (ctx->numTrustedCerts * sizeof(CSSM_DATA)),
- ((ctx->numTrustedCerts + 1) * sizeof(CSSM_DATA)));
- if(ctx->trustedCerts == NULL) {
- return SSLMemoryErr;
- }
-
- /* Now add a copy of the new root. */
- newTrustee = &ctx->trustedCerts[ctx->numTrustedCerts];
- newTrustee->Data = NULL;
- newTrustee->Length = 0;
- serr = stSetUpCssmData(newTrustee, rootCert->Length);
- if(serr) {
- return serr;
- }
- BlockMove(rootCert->Data, newTrustee->Data, rootCert->Length);
- (ctx->numTrustedCerts)++;
- return SSLNoErr;
-}
-
-#endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
-
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslKeychain.c
+
+ Contains: Apple Keychain routines
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "sslContext.h"
+#include "sslMemory.h"
+#include "appleCdsa.h"
+#include "sslDebug.h"
+#include "sslKeychain.h"
+#include "sslUtils.h"
+#include <string.h>
+#include <assert.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <Security/cssm.h>
+/* these are to be replaced by Security/Security.h */
+#include <Security/SecCertificate.h>
+#include <Security/SecKeychainItem.h>
+#include <Security/SecKeychain.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentitySearch.h>
+#include <Security/SecKey.h>
+
+#if ST_MANAGES_TRUSTED_ROOTS
+static OSStatus
+addCertData(
+ SSLContext *ctx,
+ KCItemRef kcItem,
+ CSSM_DATA_PTR certData,
+ Boolean *goodCert); /* RETURNED */
+#endif /* ST_MANAGES_TRUSTED_ROOTS */
+
+/*
+ * Given an array of certs (as SecIdentityRefs, specified by caller
+ * in SSLSetCertificate or SSLSetEncryptionCertificate) and a
+ * destination SSLCertificate:
+ *
+ * -- free destCerts if we have any
+ * -- Get raw cert data, convert to array of SSLCertificates in *destCert
+ * -- validate cert chain
+ * -- get pub, priv keys from certRef[0], store in *pubKey, *privKey
+ */
+
+/* Convert a SecCertificateRef to an SSLCertificate * */
+static OSStatus secCertToSslCert(
+ SSLContext *ctx,
+ SecCertificateRef certRef,
+ SSLCertificate **sslCert)
+{
+ CSSM_DATA certData; // struct is transient, referent owned by
+ // Sec layer
+ OSStatus ortn;
+ SSLCertificate *thisSslCert = NULL;
+
+ ortn = SecCertificateGetData(certRef, &certData);
+ if(ortn) {
+ sslErrorLog("SecCertificateGetData() returned %d\n", (int)ortn);
+ return ortn;
+ }
+
+ thisSslCert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
+ if(thisSslCert == NULL) {
+ return memFullErr;
+ }
+ if(SSLAllocBuffer(thisSslCert->derCert, certData.Length,
+ ctx)) {
+ return memFullErr;
+ }
+ memcpy(thisSslCert->derCert.data, certData.Data, certData.Length);
+ thisSslCert->derCert.length = certData.Length;
+ *sslCert = thisSslCert;
+ return noErr;
+}
+
+OSStatus
+parseIncomingCerts(
+ SSLContext *ctx,
+ CFArrayRef certs,
+ SSLCertificate **destCert, /* &ctx->{localCert,encryptCert} */
+ CSSM_KEY_PTR *pubKey, /* &ctx->signingPubKey, etc. */
+ CSSM_KEY_PTR *privKey, /* &ctx->signingPrivKey, etc. */
+ CSSM_CSP_HANDLE *cspHand /* &ctx->signingKeyCsp, etc. */
+ #if ST_KC_KEYS_NEED_REF
+ ,
+ SecKeychainRef *privKeyRef) /* &ctx->signingKeyRef, etc. */
+ #else
+ )
+ #endif /* ST_KC_KEYS_NEED_REF */
+{
+ CFIndex numCerts;
+ CFIndex cert;
+ SSLCertificate *certChain = NULL;
+ SSLCertificate *thisSslCert;
+ SecKeychainRef kcRef;
+ OSStatus ortn;
+ SecIdentityRef identity;
+ SecCertificateRef certRef;
+ SecKeyRef keyRef;
+ CSSM_DATA certData;
+ CSSM_CL_HANDLE clHand; // carefully derive from a SecCertificateRef
+ CSSM_RETURN crtn;
+
+ assert(ctx != NULL);
+ assert(destCert != NULL); /* though its referent may be NULL */
+ assert(pubKey != NULL);
+ assert(privKey != NULL);
+ assert(cspHand != NULL);
+
+ sslDeleteCertificateChain(*destCert, ctx);
+ *destCert = NULL;
+ *pubKey = NULL;
+ *privKey = NULL;
+ *cspHand = 0;
+
+ if(certs == NULL) {
+ sslErrorLog("parseIncomingCerts: NULL incoming cert array\n");
+ return errSSLBadCert;
+ }
+ numCerts = CFArrayGetCount(certs);
+ if(numCerts == 0) {
+ sslErrorLog("parseIncomingCerts: empty incoming cert array\n");
+ return errSSLBadCert;
+ }
+
+ /*
+ * Certs[0] is an SecIdentityRef from which we extract subject cert,
+ * privKey, pubKey, and cspHand.
+ *
+ * 1. ensure the first element is a SecIdentityRef.
+ */
+ identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
+ if(identity == NULL) {
+ sslErrorLog("parseIncomingCerts: bad cert array (1)\n");
+ return paramErr;
+ }
+ if(CFGetTypeID(identity) != SecIdentityGetTypeID()) {
+ sslErrorLog("parseIncomingCerts: bad cert array (2)\n");
+ return paramErr;
+ }
+
+ /*
+ * 2. Extract cert, keys, CSP handle and convert to local format.
+ */
+ ortn = SecIdentityCopyCertificate(identity, &certRef);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: bad cert array (3)\n");
+ return ortn;
+ }
+ ortn = secCertToSslCert(ctx, certRef, &thisSslCert);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: bad cert array (4)\n");
+ return ortn;
+ }
+ /* enqueue onto head of cert chain */
+ thisSslCert->next = certChain;
+ certChain = thisSslCert;
+
+ /* fetch private key from identity */
+ ortn = SecIdentityCopyPrivateKey(identity, &keyRef);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: SecIdentityCopyPrivateKey err %d\n",
+ (int)ortn);
+ return ortn;
+ }
+ ortn = SecKeyGetCSSMKey(keyRef, (const CSSM_KEY **)privKey);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: SecKeyGetCSSMKey err %d\n",
+ (int)ortn);
+ return ortn;
+ }
+ /* FIXME = release keyRef? */
+
+ /* obtain public key from cert */
+ ortn = SecCertificateGetCLHandle(certRef, &clHand);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: SecCertificateGetCLHandle err %d\n",
+ (int)ortn);
+ return ortn;
+ }
+ certData.Data = thisSslCert->derCert.data;
+ certData.Length = thisSslCert->derCert.length;
+ crtn = CSSM_CL_CertGetKeyInfo(clHand, &certData, pubKey);
+ if(crtn) {
+ sslErrorLog("parseIncomingCerts: CSSM_CL_CertGetKeyInfo err\n");
+ return (OSStatus)crtn;
+ }
+
+ /* obtain keychain from key, CSP handle from keychain */
+ ortn = SecKeychainItemCopyKeychain((SecKeychainItemRef)keyRef, &kcRef);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: SecKeychainItemCopyKeychain err %d\n",
+ (int)ortn);
+ return ortn;
+ }
+ ortn = SecKeychainGetCSPHandle(kcRef, cspHand);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: SecKeychainGetCSPHandle err %d\n",
+ (int)ortn);
+ return ortn;
+ }
+
+ /* OK, that's the subject cert. Fetch optional remaining certs. */
+ /*
+ * Convert: CFArray of SecCertificateRefs --> chain of SSLCertificates.
+ * Incoming certs have root last; SSLCertificate chain has root
+ * first.
+ */
+ for(cert=1; cert<numCerts; cert++) {
+ certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certs, cert);
+ if(certRef == NULL) {
+ sslErrorLog("parseIncomingCerts: bad cert array (5)\n");
+ return paramErr;
+ }
+ if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) {
+ sslErrorLog("parseIncomingCerts: bad cert array (6)\n");
+ return paramErr;
+ }
+
+ /* Extract cert, convert to local format.
+ */
+ ortn = secCertToSslCert(ctx, certRef, &thisSslCert);
+ if(ortn) {
+ sslErrorLog("parseIncomingCerts: bad cert array (7)\n");
+ return ortn;
+ }
+ /* enqueue onto head of cert chain */
+ thisSslCert->next = certChain;
+ certChain = thisSslCert;
+ }
+
+ /* validate the whole mess, skipping host name verify */
+ ortn = sslVerifyCertChain(ctx, *certChain, false);
+ if(ortn) {
+ goto errOut;
+ }
+
+ /* SUCCESS */
+ *destCert = certChain;
+ return noErr;
+
+errOut:
+ /* free certChain, everything in it, other vars, return ortn */
+ sslDeleteCertificateChain(certChain, ctx);
+ /* FIXME - anything else? */
+ return ortn;
+}
+
+/*
+ * Add Apple built-in root certs to ctx->trustedCerts.
+ */
+OSStatus addBuiltInCerts (SSLContextRef ctx)
+{
+ #if ST_MANAGES_TRUSTED_ROOTS
+ OSStatus ortn;
+ KCRef kc = nil;
+
+ ortn = KCDispatch(kKCGetRootCertificateKeychain, &kc);
+ if(ortn) {
+ sslErrorLog("KCDispatch(kKCGetRootCertificateKeychain) returned %d\n",
+ ortn);
+ return ortn;
+ }
+ return parseTrustedKeychain(ctx, kc);
+ #else
+ /* nothing for now */
+ return noErr;
+ #endif /* ST_MANAGES_TRUSTED_ROOTS */
+}
+
+#if ST_MANAGES_TRUSTED_ROOTS
+
+/*
+ * Given an open Keychain:
+ * -- Get raw cert data, add to array of CSSM_DATAs in
+ * ctx->trustedCerts
+ * -- verify that each of these is a valid (self-verifying)
+ * root cert
+ * -- add each subject name to acceptableDNList
+ */
+OSStatus
+parseTrustedKeychain (SSLContextRef ctx,
+ KCRef keyChainRef)
+{
+ CFMutableArrayRef kcCerts = NULL; /* all certs in one keychain */
+ uint32 numGoodCerts = 0; /* # of good root certs */
+ CSSM_DATA_PTR certData = NULL; /* array of CSSM_DATAs */
+ CFIndex certDex; /* index into kcCerts */
+ CFIndex certsPerKc; /* # of certs in this KC */
+ OSStatus ortn;
+ KCItemRef kcItem; /* one cert */
+ Boolean goodCert;
+
+ assert(ctx != NULL);
+ if(keyChainRef == NULL) {
+ return paramErr;
+ }
+
+ ortn = KCFindX509Certificates(keyChainRef,
+ NULL, // name, XXX
+ NULL, // emailAddress, XXX
+ kCertSearchAny, // options
+ &kcCerts); // results
+ switch(ortn) {
+ case noErr:
+ break; // proceed
+ case errKCItemNotFound:
+ return noErr; // no certs; done
+ default:
+ sslErrorLog("parseTrustedKeychains: KCFindX509Certificates returned %d\n",
+ ortn);
+ return ortn;
+ }
+ if(kcCerts == NULL) {
+ sslErrorLog("parseTrustedKeychains: no certs in KC\n");
+ return noErr;
+ }
+
+ /* Note kcCerts must be released on any exit, successful or
+ * otherwise. */
+
+ certsPerKc = CFArrayGetCount(kcCerts);
+
+ /*
+ * This array gets allocd locally; we'll add it to
+ * ctx->trustedCerts when we're done.
+ */
+ certData = sslMalloc(certsPerKc * sizeof(CSSM_DATA));
+ if(certData == NULL) {
+ ortn = memFullErr;
+ goto errOut;
+ }
+ memset(certData, 0, certsPerKc * sizeof(CSSM_DATA));
+
+ /*
+ * Build up local certData one root cert at a time.
+ * Some certs might not pass muster, hence the numGoodCerts
+ * which may or may not increment each time thru.
+ */
+ for(certDex=0; certDex<certsPerKc; certDex++) {
+ kcItem = (KCItemRef)CFArrayGetValueAtIndex(kcCerts, certDex);
+ if(kcItem == NULL) {
+ sslErrorLog("parseTrustedKeychains: CF error 1\n");
+ ortn = errSSLInternal;
+ goto errOut;
+ }
+ if(!KCIsRootCertificate(kcItem)) {
+ /* not root, OK, skip to next cert */
+ sslErrorLog("parseTrustedKeychains: cert %d NOT ROOT\n",
+ certDex);
+ continue;
+ }
+ ortn = addCertData(ctx,
+ kcItem,
+ &certData[numGoodCerts],
+ &goodCert);
+ if(ortn) {
+ goto errOut;
+ }
+ if(goodCert) {
+ /* added valid root to certData */
+ numGoodCerts++;
+ }
+ } /* for each cert in kcCerts */
+
+ #if SSL_DEBUG
+ verifyTrustedRoots(ctx, certData, numGoodCerts);
+ #endif
+
+ /* Realloc ctx->trustedCerts, add new root certs */
+ ctx->trustedCerts = sslRealloc(ctx->trustedCerts,
+ ctx->numTrustedCerts * sizeof(CSSM_DATA),
+ (ctx->numTrustedCerts + numGoodCerts) * sizeof(CSSM_DATA));
+ if(ctx->trustedCerts == NULL) {
+ ortn = memFullErr;
+ goto errOut;
+ }
+ for(certDex=0; certDex<numGoodCerts; certDex++) {
+ ctx->trustedCerts[ctx->numTrustedCerts + certDex] = certData[certDex];
+ }
+ ctx->numTrustedCerts += numGoodCerts;
+ ortn = noErr;
+
+ #if SSL_DEBUG
+ verifyTrustedRoots(ctx, ctx->trustedCerts, ctx->numTrustedCerts);
+ #endif
+
+errOut:
+ sslFree(certData);
+ if(kcCerts != NULL) {
+ CFRelease(kcCerts);
+ }
+ return ortn;
+}
+
+/*
+ * Given a (supposedly) root cert as a KCItemRef:
+ * -- verify that the cert self-verifies
+ * -- add its DER-encoded data *certData.
+ * -- Add its subjectName to acceptableDNList.
+ * -- If all is well, return True in *goodCert.
+ *
+ * The actual CSSM_DATA.Data is mallocd via CSSM_Malloc.
+ */
+static OSStatus
+addCertData(
+ SSLContext *ctx,
+ KCItemRef kcItem,
+ CSSM_DATA_PTR certData,
+ Boolean *goodCert) /* RETURNED */
+{
+ UInt32 certSize;
+ OSStatus ortn;
+ CSSM_BOOL subjectExpired;
+
+ assert(ctx != NULL);
+ assert(certData != NULL);
+ assert(kcItem != NULL);
+ assert(goodCert != NULL);
+
+ *goodCert = false;
+
+ /* how big is the cert? */
+ ortn = KCGetData (kcItem, 0, NULL, &certSize);
+ if(ortn != noErr) {
+ sslErrorLog("addCertData: KCGetData(1) returned %d\n", ortn);
+ return ortn;
+ }
+
+ /* Allocate the buffer. */
+ ortn = stSetUpCssmData(certData, certSize);
+ if(ortn) {
+ return ortn;
+ }
+
+ /* Get the data. */
+ ortn = KCGetData (kcItem, certSize, certData->Data, &certSize);
+ if(ortn) {
+ sslErrorLog("addCertData: KCGetData(2) returned %d\n", ortn);
+ stFreeCssmData(certData, CSSM_FALSE);
+ return ortn;
+ }
+
+ /*
+ * Do actual cert verify, which
+ * KCIsRootCertificate does not do. A failure isn't
+ * fatal; we just don't add the cert to the array in
+ * that case.
+ *
+ * FIXME - we assume here that our common cspHand can
+ * do this cert verify; if not, we have some API work to
+ * do (to let the caller specify which CSP to use with
+ * trusted certs).
+ */
+ if(!sslVerifyCert(ctx,
+ certData,
+ certData,
+ ctx->cspHand,
+ &subjectExpired)) {
+ sslErrorLog("addCertData: cert does not self-verify!\n");
+ stFreeCssmData(certData, CSSM_FALSE);
+ return noErr;
+ }
+
+ /* FIXME - needs update for MANAGES_TRUSTED_ROOTS */
+ /* Add this cert's subject name to (poss. existing) acceptableDNList */
+ CSSM_DATA_PTR dnData = sslGetCertSubjectName(ctx, certData);
+ if(dnData) {
+ DNListElem *dn = sslMalloc(sizeof(DNListElem));
+ if(dn == NULL) {
+ return memFullErr;
+ }
+ dn->next = ctx->acceptableDNList;
+ ctx->acceptableDNList = dn;
+
+ /* move actual data to dn; free the CSSM_DATA struct (must be
+ * via CSSM_Free()!) */
+ CSSM_TO_SSLBUF(dnData, &dn->derDN);
+ sslFree(dnData);
+ }
+
+ *goodCert = true;
+ return noErr;
+}
+
+/*
+ * Given a newly encountered root cert (obtained from a peer's cert chain),
+ * add it to newRootCertKc if the user so allows, and if so, add it to
+ * trustedCerts.
+ */
+OSStatus
+sslAddNewRoot(
+ SSLContext *ctx,
+ const CSSM_DATA_PTR rootCert)
+{
+ KCRef defaultKc;
+ Boolean bDefaultKcExists;
+ KCItemRef certRef = NULL;
+ OSStatus ortn;
+ CSSM_DATA_PTR newTrustee;
+ OSStatus serr;
+
+ assert(ctx != NULL);
+ assert(rootCert != NULL);
+ assert(ctx->newRootCertKc != NULL); /* caller verifies this */
+
+ /*
+ * Get default KC, temporarily set new default.
+ */
+ ortn = KCGetDefaultKeychain(&defaultKc);
+ if(ortn) {
+ bDefaultKcExists = false;
+ }
+ else {
+ bDefaultKcExists = true;
+ }
+ ortn = KCSetDefaultKeychain(ctx->newRootCertKc);
+ if(ortn) {
+ sslErrorLog("sslAddNewRoot: KCSetDefaultKeychain returned %d\n", ortn);
+ return errSSLUnknownRootCert;
+ }
+
+ /*
+ * Add cert to newRootCertKc. This may well fail due to user
+ * interaction ("Do you want to add this root cert...?").
+ */
+ ortn = KCAddX509Certificate(rootCert->Data, rootCert->Length, &certRef);
+
+ /* restore default KC in any case */
+ if(bDefaultKcExists) {
+ KCSetDefaultKeychain(defaultKc);
+ }
+ if(ortn) {
+ sslErrorLog("sslAddNewRoot: KCAddX509Certificate returned %d\n", ortn);
+ return errSSLUnknownRootCert;
+ }
+
+ /*
+ * OK, user accepted new root. Now add to our private stash of
+ * trusted roots. Realloc the whole pile...
+ */
+ ctx->trustedCerts = (CSSM_DATA_PTR)sslRealloc(ctx->trustedCerts,
+ (ctx->numTrustedCerts * sizeof(CSSM_DATA)),
+ ((ctx->numTrustedCerts + 1) * sizeof(CSSM_DATA)));
+ if(ctx->trustedCerts == NULL) {
+ return memFullErr;
+ }
+
+ /* Now add a copy of the new root. */
+ newTrustee = &ctx->trustedCerts[ctx->numTrustedCerts];
+ newTrustee->Data = NULL;
+ newTrustee->Length = 0;
+ serr = stSetUpCssmData(newTrustee, rootCert->Length);
+ if(serr) {
+ return serr;
+ }
+ BlockMove(rootCert->Data, newTrustee->Data, rootCert->Length);
+ (ctx->numTrustedCerts)++;
+ return noErr;
+}
+
+#endif /* ST_MANAGES_TRUSTED_ROOTS */
+
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslMemory.c
+
+ Contains: memory allocator implementation
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslMemory.h"
+#include "sslContext.h"
+#include "sslDebug.h"
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#pragma mark *** Basic low-level malloc/free ***
+
+/*
+ * For now, all allocs/frees go thru here.
+ */
+#include <string.h> /* memset */
+#include <stdlib.h>
+
+void *
+sslMalloc(UInt32 length)
+{
+ return malloc(length);
+}
+
+void
+sslFree(void *p)
+{
+ if(p != nil) {
+ free(p);
+ }
+}
+
+void *
+sslRealloc(void *oldPtr, UInt32 oldLen, UInt32 newLen)
+{
+ return realloc(oldPtr, newLen);
+}
+
+#pragma mark *** SSLBuffer-level alloc/free ***
+
+OSStatus SSLAllocBuffer(
+ SSLBuffer &buf,
+ UInt32 length,
+ const SSLContext *ctx) // currently unused
+{
+ buf.data = (UInt8 *)sslMalloc(length);
+ if(buf.data == NULL) {
+ buf.length = 0;
+ return memFullErr;
+ }
+ buf.length = length;
+ return noErr;
+}
+
+OSStatus
+SSLFreeBuffer(SSLBuffer &buf, const SSLContext *ctx)
+{
+ if(&buf == NULL) {
+ sslErrorLog("SSLFreeBuffer: NULL buf!\n");
+ return errSSLInternal;
+ }
+ sslFree(buf.data);
+ buf.data = NULL;
+ buf.length = 0;
+ return noErr;
+}
+
+OSStatus
+SSLReallocBuffer(SSLBuffer &buf, UInt32 newSize, const SSLContext *ctx)
+{
+ buf.data = (UInt8 *)sslRealloc(buf.data, buf.length, newSize);
+ if(buf.data == NULL) {
+ buf.length = 0;
+ return memFullErr;
+ }
+ buf.length = newSize;
+ return noErr;
+}
+
+#pragma mark *** Convenience routines ***
+
+UInt8 *sslAllocCopy(
+ const UInt8 *src,
+ UInt32 len)
+{
+ UInt8 *dst;
+
+ dst = (UInt8 *)sslMalloc(len);
+ if(dst == NULL) {
+ return NULL;
+ }
+ memmove(dst, src, len);
+ return dst;
+}
+
+OSStatus SSLAllocCopyBuffer(
+ const SSLBuffer &src,
+ SSLBuffer **dst) // buffer and data mallocd and returned
+{
+ OSStatus serr;
+
+ SSLBuffer *rtn = (SSLBuffer *)sslMalloc(sizeof(SSLBuffer));
+ if(rtn == NULL) {
+ return memFullErr;
+ }
+ serr = SSLCopyBuffer(src, *rtn);
+ if(serr) {
+ sslFree(rtn);
+ }
+ else {
+ *dst = rtn;
+ }
+ return serr;
+}
+
+OSStatus SSLCopyBuffer(
+ const SSLBuffer &src,
+ SSLBuffer &dst) // data mallocd and returned
+{
+ dst.data = sslAllocCopy(src.data, src.length);
+ if(dst.data == NULL) {
+ return memFullErr;
+ }
+ dst.length = src.length;
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+#include "sslContext.h"
+
+#include <string.h>
+
+static OSStatus NullInit(
+ uint8 *key,
+ uint8* iv,
+ CipherContext *cipherCtx,
+ SSLContext *ctx);
+static OSStatus NullCrypt(
+ SSLBuffer src,
+ SSLBuffer dest,
+ CipherContext *cipherCtx,
+ SSLContext *ctx);
+static OSStatus NullFinish(
+ CipherContext *cipherCtx,
+ SSLContext *ctx);
+
+extern "C" {
+extern const SSLSymmetricCipher SSLCipherNull;
+}
+const SSLSymmetricCipher SSLCipherNull = {
+ 0, /* Key size in bytes (ignoring parity) */
+ 0, /* Secret key size */
+ 0, /* IV size */
+ 0, /* Block size */
+ CSSM_ALGID_NONE,
+ CSSM_ALGID_NONE,
+ CSSM_ALGMODE_NONE,
+ CSSM_PADDING_NONE,
+ NullInit,
+ NullCrypt,
+ NullCrypt,
+ NullFinish
+};
+
+static OSStatus NullInit(
+ uint8 *key,
+ uint8* iv,
+ CipherContext *cipherCtx,
+ SSLContext *ctx)
+{
+ return noErr;
+}
+
+static OSStatus NullCrypt(
+ SSLBuffer src,
+ SSLBuffer dest,
+ CipherContext *cipherCtx,
+ SSLContext *ctx)
+{
+ if (src.data != dest.data)
+ memcpy(dest.data, src.data, src.length);
+ return noErr;
+}
+
+static OSStatus NullFinish(
+ CipherContext *cipherCtx,
+ SSLContext *ctx)
+{
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslRecord.cpp
+
+ Contains: Encryption, decryption and MACing of data
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+
+#include "sslRecord.h"
+#include "sslMemory.h"
+#include "cryptType.h"
+#include "sslContext.h"
+#include "sslAlertMessage.h"
+#include "sslDebug.h"
+#include "ssl2.h"
+#include "sslUtils.h"
+#include "sslDigests.h"
+
+#include <string.h>
+#include <assert.h>
+
+/*
+ * Lots of servers fail to provide closure alerts when they disconnect.
+ * For now we'll just accept it as long as it occurs on a clean record boundary
+ * (and the handshake is complete).
+ */
+#define SSL_ALLOW_UNNOTICED_DISCONNECT 1
+
+/* ReadSSLRecord
+ * Attempt to read & decrypt an SSL record.
+ */
+OSStatus
+SSLReadRecord(SSLRecord &rec, SSLContext *ctx)
+{ OSStatus err;
+ UInt32 len, contentLen;
+ UInt8 *charPtr;
+ SSLBuffer readData, cipherFragment;
+
+ if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < 5)
+ { if (ctx->partialReadBuffer.data)
+ if ((err = SSLFreeBuffer(ctx->partialReadBuffer, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ if ((err = SSLAllocBuffer(ctx->partialReadBuffer,
+ DEFAULT_BUFFER_SIZE, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+
+ if (ctx->negProtocolVersion == SSL_Version_Undetermined ||
+ ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
+ if (ctx->amountRead < 1)
+ { readData.length = 1 - ctx->amountRead;
+ readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+ len = readData.length;
+ err = sslIoRead(readData, &len, ctx);
+ if(err != 0)
+ { if (err == errSSLWouldBlock)
+ ctx->amountRead += len;
+ else
+ SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ ctx->amountRead += len;
+ }
+
+ /*
+ * In undetermined cases, if the first byte isn't in the range of SSL 3.0
+ * record types, this is an SSL 2.0 record
+ */
+ switch (ctx->negProtocolVersion)
+ { case SSL_Version_Undetermined:
+ case SSL_Version_3_0_With_2_0_Hello:
+ if (ctx->partialReadBuffer.data[0] < SSL_RecordTypeV3_Smallest ||
+ ctx->partialReadBuffer.data[0] > SSL_RecordTypeV3_Largest)
+ return SSL2ReadRecord(rec, ctx);
+ else
+ break;
+ case SSL_Version_2_0:
+ return SSL2ReadRecord(rec, ctx);
+ default:
+ break;
+ }
+
+ if (ctx->amountRead < 5)
+ { readData.length = 5 - ctx->amountRead;
+ readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+ len = readData.length;
+ err = sslIoRead(readData, &len, ctx);
+ if(err != 0)
+ {
+ switch(err) {
+ case errSSLWouldBlock:
+ ctx->amountRead += len;
+ break;
+ #if SSL_ALLOW_UNNOTICED_DISCONNECT
+ case errSSLClosedGraceful:
+ /* legal if we're on record boundary and we've gotten past
+ * the handshake */
+ if((ctx->amountRead == 0) && /* nothing pending */
+ (len == 0) && /* nothing new */
+ (ctx->state == SSL2_HdskStateClientReady)) { /* handshake done */
+ /*
+ * This means that the server has disconnected without
+ * sending a closure alert notice. This is technically
+ * illegal per the SSL3 spec, but about half of the
+ * servers out there do it, so we report it as a separate
+ * error which most clients - including (currently)
+ * URLAccess - ignore by treating it the same as
+ * a errSSLClosedGraceful error. Paranoid
+ * clients can detect it and handle it however they
+ * want to.
+ */
+ SSLChangeHdskState(ctx, SSL_HdskStateNoNotifyClose);
+ err = errSSLClosedNoNotify;
+ break;
+ }
+ else {
+ /* illegal disconnect */
+ err = errSSLClosedAbort;
+ /* and drop thru to default: fatal alert */
+ }
+ #endif /* SSL_ALLOW_UNNOTICED_DISCONNECT */
+ default:
+ SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ break;
+ }
+ return err;
+ }
+ ctx->amountRead += len;
+ }
+
+ assert(ctx->amountRead >= 5);
+
+ charPtr = ctx->partialReadBuffer.data;
+ rec.contentType = *charPtr++;
+ if (rec.contentType < SSL_RecordTypeV3_Smallest ||
+ rec.contentType > SSL_RecordTypeV3_Largest)
+ return errSSLProtocol;
+
+ rec.protocolVersion = (SSLProtocolVersion)SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ contentLen = SSLDecodeInt(charPtr, 2);
+ charPtr += 2;
+ if (contentLen > (16384 + 2048)) /* Maximum legal length of an
+ * SSLCipherText payload */
+ { SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ return errSSLProtocol;
+ }
+
+ if (ctx->partialReadBuffer.length < 5 + contentLen)
+ { if ((err = SSLReallocBuffer(ctx->partialReadBuffer, 5 + contentLen, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ }
+
+ if (ctx->amountRead < 5 + contentLen)
+ { readData.length = 5 + contentLen - ctx->amountRead;
+ readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+ len = readData.length;
+ err = sslIoRead(readData, &len, ctx);
+ if(err != 0)
+ { if (err == errSSLWouldBlock)
+ ctx->amountRead += len;
+ else
+ SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ ctx->amountRead += len;
+ }
+
+ assert(ctx->amountRead >= 5 + contentLen);
+
+ cipherFragment.data = ctx->partialReadBuffer.data + 5;
+ cipherFragment.length = contentLen;
+
+ /*
+ * Decrypt the payload & check the MAC, modifying the length of the
+ * buffer to indicate the amount of plaintext data after adjusting
+ * for the block size and removing the MAC (this function generates
+ * its own alerts).
+ */
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->decryptRecord(rec.contentType,
+ &cipherFragment, ctx)) != 0)
+ return err;
+
+ /*
+ * We appear to have sucessfully received a record; increment the
+ * sequence number
+ */
+ IncrementUInt64(&ctx->readCipher.sequenceNum);
+
+ /* Allocate a buffer to return the plaintext in and return it */
+ if ((err = SSLAllocBuffer(rec.contents, cipherFragment.length, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+ memcpy(rec.contents.data, cipherFragment.data, cipherFragment.length);
+
+ ctx->amountRead = 0; /* We've used all the data in the cache */
+
+ return noErr;
+}
+
+/* common for sslv3 and tlsv1, except for the computeMac callout */
+OSStatus SSLVerifyMac(
+ UInt8 type,
+ SSLBuffer &data,
+ UInt8 *compareMAC,
+ SSLContext *ctx)
+{
+ OSStatus err;
+ UInt8 macData[SSL_MAX_DIGEST_LEN];
+ SSLBuffer secret, mac;
+
+ secret.data = ctx->readCipher.macSecret;
+ secret.length = ctx->readCipher.macRef->hash->digestSize;
+ mac.data = macData;
+ mac.length = ctx->readCipher.macRef->hash->digestSize;
+
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->computeMac(type,
+ data,
+ mac,
+ &ctx->readCipher,
+ ctx->readCipher.sequenceNum,
+ ctx)) != 0)
+ return err;
+
+ if ((memcmp(mac.data, compareMAC, mac.length)) != 0) {
+ sslErrorLog("ssl3VerifyMac: Mac verify failure\n");
+ return errSSLProtocol;
+ }
+ return noErr;
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+#include "ssl.h"
+#include "sslContext.h"
+#include "sslSession.h"
+#include "sslMemory.h"
+#include "sslUtils.h"
+#include "sslDebug.h"
+#include "cipherSpecs.h"
+#include "appleSession.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stddef.h>
+
+typedef struct
+{ int sessionIDLen;
+ UInt8 sessionID[32];
+ SSLProtocolVersion protocolVersion;
+ UInt16 cipherSuite;
+ UInt16 padding; /* so remainder is word aligned */
+ UInt8 masterSecret[48];
+ int certCount;
+ UInt8 certs[1]; /* Actually, variable length */
+} ResumableSession;
+
+/*
+ * Cook up a (private) resumable session blob, based on the
+ * specified ctx, store it with ctx->peerID as the key.
+ * NOTE: This is contrary to the SSL v3 spec, which claims that
+ * servers store resumable sessions using ctx->sessionID as the key.
+ * I don' think this is an issue...is it?
+ */
+OSStatus
+SSLAddSessionData(const SSLContext *ctx)
+{ OSStatus err;
+ uint32 sessionIDLen;
+ SSLBuffer sessionID;
+ ResumableSession *session;
+ int certCount;
+ SSLCertificate *cert;
+ uint8 *certDest;
+
+ /* If we don't know who the peer is, we can't store a session */
+ if (ctx->peerID.data == 0)
+ return errSSLSessionNotFound;
+
+ sessionIDLen = offsetof(ResumableSession, certs);
+ cert = ctx->peerCert;
+ certCount = 0;
+ while (cert)
+ { ++certCount;
+ sessionIDLen += 4 + cert->derCert.length;
+ cert = cert->next;
+ }
+
+ if ((err = SSLAllocBuffer(sessionID, sessionIDLen, ctx)) != 0)
+ return err;
+
+ session = (ResumableSession*)sessionID.data;
+
+ session->sessionIDLen = ctx->sessionID.length;
+ memcpy(session->sessionID, ctx->sessionID.data, session->sessionIDLen);
+ session->protocolVersion = ctx->negProtocolVersion;
+ session->cipherSuite = ctx->selectedCipher;
+ memcpy(session->masterSecret, ctx->masterSecret, 48);
+ session->certCount = certCount;
+ session->padding = 0;
+
+ certDest = session->certs;
+ cert = ctx->peerCert;
+ while (cert)
+ { certDest = SSLEncodeInt(certDest, cert->derCert.length, 4);
+ memcpy(certDest, cert->derCert.data, cert->derCert.length);
+ certDest += cert->derCert.length;
+ cert = cert->next;
+ }
+
+ err = sslAddSession(ctx->peerID, sessionID);
+ SSLFreeBuffer(sessionID, ctx);
+
+ return err;
+}
+
+/*
+ * Retrieve resumable session data, from key ctx->peerID.
+ */
+OSStatus
+SSLGetSessionData(SSLBuffer *sessionData, const SSLContext *ctx)
+{ OSStatus err;
+
+ if (ctx->peerID.data == 0)
+ return errSSLSessionNotFound;
+
+ sessionData->data = 0;
+
+ err = sslGetSession(ctx->peerID, sessionData);
+ if (sessionData->data == 0)
+ return errSSLSessionNotFound;
+
+ return err;
+}
+
+OSStatus
+SSLDeleteSessionData(const SSLContext *ctx)
+{ OSStatus err;
+
+ if (ctx->peerID.data == 0)
+ return errSSLSessionNotFound;
+
+ err = sslDeleteSession(ctx->peerID);
+ return err;
+}
+
+/*
+ * Given a sessionData blob, obtain the associated sessionID (NOT the key...).
+ */
+OSStatus
+SSLRetrieveSessionID(
+ const SSLBuffer sessionData,
+ SSLBuffer *identifier,
+ const SSLContext *ctx)
+{ OSStatus err;
+ ResumableSession *session;
+
+ session = (ResumableSession*) sessionData.data;
+ if ((err = SSLAllocBuffer(*identifier, session->sessionIDLen, ctx)) != 0)
+ return err;
+ memcpy(identifier->data, session->sessionID, session->sessionIDLen);
+ return noErr;
+}
+
+/*
+ * Obtain the protocol version associated with a specified resumable session blob.
+ */
+OSStatus
+SSLRetrieveSessionProtocolVersion(
+ const SSLBuffer sessionData,
+ SSLProtocolVersion *version,
+ const SSLContext *ctx)
+{ ResumableSession *session;
+
+ session = (ResumableSession*) sessionData.data;
+ *version = session->protocolVersion;
+ return noErr;
+}
+
+/*
+ * Retrieve session state from specified sessionData blob, install into
+ * ctx. Presumably, ctx->sessionID and
+ * ctx->negProtocolVersion are already init'd (from the above two functions).
+ */
+
+/*
+ * Netscape Enterprise Server is known to change cipherspecs upon session resumption.
+ * For example, connecting to cdnow.com with all ciphersuites enabled results in
+ * CipherSuite 4 (SSL_RSA_WITH_RC4_128_MD5) being selected on the first session,
+ * and CipherSuite 10 (SSL_RSA_WITH_3DES_EDE_CBC_SHA) being selected on subsequent
+ * sessions. This is contrary to the SSL3.0 spec, sesion 7.6.1.3, describing the
+ * Server Hello message.
+ *
+ * This anomaly does not occur if only RC4 ciphers are enabled in the Client Hello
+ * message. It also does not happen in SSL V2.
+ */
+#define ALLOW_CIPHERSPEC_CHANGE 1
+
+OSStatus
+SSLInstallSessionFromData(const SSLBuffer sessionData, SSLContext *ctx)
+{ OSStatus err;
+ ResumableSession *session;
+ uint8 *storedCertProgress;
+ SSLCertificate *cert, *lastCert;
+ int certCount;
+ uint32 certLen;
+
+ session = (ResumableSession*)sessionData.data;
+
+ assert(ctx->negProtocolVersion == session->protocolVersion);
+
+ /*
+ * For SSLv3 and TLSv1, we know that selectedCipher has already been specified in
+ * SSLProcessServerHello(). An SSLv2 server hello message with a session
+ * ID hit contains no CipherKind field so we set it here.
+ */
+ if(ctx->negProtocolVersion == SSL_Version_2_0) {
+ if(ctx->protocolSide == SSL_ClientSide) {
+ assert(ctx->selectedCipher == 0);
+ ctx->selectedCipher = session->cipherSuite;
+ }
+ else {
+ /*
+ * Else...what if they don't match? Could never happen, right?
+ * Wouldn't that mean the client is trying to switch ciphers on us?
+ */
+ if(ctx->selectedCipher != session->cipherSuite) {
+ sslErrorLog("+++SSL2: CipherSpec change from %d to %d on session "
+ "resume\n",
+ session->cipherSuite, ctx->selectedCipher);
+ return errSSLProtocol;
+ }
+ }
+ }
+ else {
+ assert(ctx->selectedCipher != 0);
+ if(ctx->selectedCipher != session->cipherSuite) {
+ #if ALLOW_CIPHERSPEC_CHANGE
+ sslErrorLog("+++WARNING: CipherSpec change from %d to %d "
+ "on session resume\n",
+ session->cipherSuite, ctx->selectedCipher);
+ #else
+ sslErrorLog("+++SSL: CipherSpec change from %d to %d on session resume\n",
+ session->cipherSuite, ctx->selectedCipher);
+ return errSSLProtocol;
+ #endif
+ }
+ }
+ if ((err = FindCipherSpec(ctx)) != 0) {
+ return err;
+ }
+ memcpy(ctx->masterSecret, session->masterSecret, 48);
+
+ lastCert = 0;
+ storedCertProgress = session->certs;
+ certCount = session->certCount;
+
+ while (certCount--)
+ {
+ cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
+ if(cert == NULL) {
+ return memFullErr;
+ }
+ cert->next = 0;
+ certLen = SSLDecodeInt(storedCertProgress, 4);
+ storedCertProgress += 4;
+ if ((err = SSLAllocBuffer(cert->derCert, certLen, ctx)) != 0)
+ {
+ sslFree(cert);
+ return err;
+ }
+ memcpy(cert->derCert.data, storedCertProgress, certLen);
+ storedCertProgress += certLen;
+ if (lastCert == 0)
+ ctx->peerCert = cert;
+ else
+ lastCert->next = cert;
+ lastCert = cert;
+ }
+
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslTransport.c
+
+ Contains: SSL transport layer
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslMemory.h"
+#include "sslContext.h"
+#include "sslRecord.h"
+#include "sslAlertMessage.h"
+#include "sslSession.h"
+#include "ssl2.h"
+#include "sslDebug.h"
+#include "cipherSpecs.h"
+#include "sslUtils.h"
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#include <assert.h>
+#include <string.h>
+
+#ifndef NDEBUG
+static void inline sslIoTrace(
+ const char *op,
+ UInt32 req,
+ UInt32 moved,
+ OSStatus stat)
+{
+ sslLogRecordIo("===%s: req %4lu moved %4lu status %ld\n",
+ op, req, moved, stat);
+}
+#else
+#define sslIoTrace(op, req, moved, stat)
+#endif /* NDEBUG */
+
+static OSStatus SSLProcessProtocolMessage(SSLRecord &rec, SSLContext *ctx);
+static OSStatus SSLHandshakeProceed(SSLContext *ctx);
+static OSStatus SSLInitConnection(SSLContext *ctx);
+static OSStatus SSLServiceWriteQueue(SSLContext *ctx);
+
+OSStatus
+SSLWrite(
+ SSLContext *ctx,
+ const void * data,
+ UInt32 dataLength,
+ UInt32 *bytesWritten) /* RETURNED */
+{
+ OSStatus err;
+ SSLRecord rec;
+ UInt32 dataLen, processed;
+
+ if((ctx == NULL) || (bytesWritten == NULL)) {
+ return paramErr;
+ }
+ dataLen = dataLength;
+ processed = 0; /* Initialize in case we return with errSSLWouldBlock */
+ *bytesWritten = 0;
+
+ switch(ctx->state) {
+ case SSL_HdskStateGracefulClose:
+ err = errSSLClosedGraceful;
+ goto abort;
+ case SSL_HdskStateErrorClose:
+ err = errSSLClosedAbort;
+ goto abort;
+ default:
+ /* FIXME - original code didn't check for pending handshake -
+ * should we?
+ */
+ sslIoTrace("SSLWrite", dataLength, 0, badReqErr);
+ return badReqErr;
+ case SSL2_HdskStateServerReady:
+ case SSL2_HdskStateClientReady:
+ break;
+ }
+
+ /* First, we have to wait until the session is ready to send data,
+ so the encryption keys and such have been established. */
+ err = noErr;
+ while (ctx->writeCipher.ready == 0)
+ { if ((err = SSLHandshakeProceed(ctx)) != 0)
+ goto exit;
+ }
+
+ /* Attempt to empty the write queue before queueing more data */
+ if ((err = SSLServiceWriteQueue(ctx)) != 0)
+ goto abort;
+
+ processed = 0;
+ /*
+ * Fragment, package and encrypt the data and queue the resulting data
+ * for sending
+ */
+ while (dataLen > 0)
+ { rec.contentType = SSL_RecordTypeAppData;
+ rec.protocolVersion = ctx->negProtocolVersion;
+ rec.contents.data = ((UInt8*)data) + processed;
+
+ if (dataLen < MAX_RECORD_LENGTH)
+ rec.contents.length = dataLen;
+ else
+ rec.contents.length = MAX_RECORD_LENGTH;
+
+ assert(ctx->sslTslCalls != NULL);
+ if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+ goto exit;
+ processed += rec.contents.length;
+ dataLen -= rec.contents.length;
+ }
+
+ /* All the data has been advanced to the write queue */
+ *bytesWritten = processed;
+ if ((err = SSLServiceWriteQueue(ctx)) == 0) {
+ err = noErr;
+ }
+exit:
+ if (err != 0 && err != errSSLWouldBlock && err != errSSLClosedGraceful) {
+ sslErrorLog("SSLWrite: going to state errorCLose due to err %d\n",
+ (int)err);
+ SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
+ }
+abort:
+ sslIoTrace("SSLWrite", dataLength, *bytesWritten, err);
+ return err;
+}
+
+OSStatus
+SSLRead (
+ SSLContext *ctx,
+ void * data,
+ UInt32 dataLength,
+ UInt32 *processed) /* RETURNED */
+{
+ OSStatus err;
+ UInt8 *charPtr;
+ UInt32 bufSize, remaining, count;
+ SSLRecord rec;
+
+ if((ctx == NULL) || (processed == NULL)) {
+ return paramErr;
+ }
+ bufSize = dataLength;
+ *processed = 0; /* Initialize in case we return with errSSLWouldBlock */
+
+ /* first handle cases in which we know we're finished */
+ switch(ctx->state) {
+ case SSL_HdskStateGracefulClose:
+ err = errSSLClosedGraceful;
+ goto abort;
+ case SSL_HdskStateErrorClose:
+ err = errSSLClosedAbort;
+ goto abort;
+ case SSL_HdskStateNoNotifyClose:
+ err = errSSLClosedNoNotify;
+ goto abort;
+ default:
+ break;
+ }
+
+ /* First, we have to wait until the session is ready to receive data,
+ so the encryption keys and such have been established. */
+ err = noErr;
+ while (ctx->readCipher.ready == 0) {
+ if ((err = SSLHandshakeProceed(ctx)) != 0) {
+ goto exit;
+ }
+ }
+
+ /* Attempt to service the write queue */
+ if ((err = SSLServiceWriteQueue(ctx)) != 0) {
+ if (err != errSSLWouldBlock) {
+ goto exit;
+ }
+ err = noErr; /* Write blocking shouldn't stop attempts to read */
+ }
+
+ remaining = bufSize;
+ charPtr = (UInt8*)data;
+ if (ctx->receivedDataBuffer.data)
+ { count = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
+ if (count > bufSize)
+ count = bufSize;
+ memcpy(data, ctx->receivedDataBuffer.data + ctx->receivedDataPos, count);
+ remaining -= count;
+ charPtr += count;
+ *processed += count;
+ ctx->receivedDataPos += count;
+ }
+
+ assert(ctx->receivedDataPos <= ctx->receivedDataBuffer.length);
+ assert(*processed + remaining == bufSize);
+ assert(charPtr == ((UInt8*)data) + *processed);
+
+ if (ctx->receivedDataBuffer.data != 0 &&
+ ctx->receivedDataPos >= ctx->receivedDataBuffer.length)
+ { SSLFreeBuffer(ctx->receivedDataBuffer, ctx);
+ ctx->receivedDataBuffer.data = 0;
+ ctx->receivedDataPos = 0;
+ }
+
+ /*
+ * This while statement causes a hang when using nonblocking low-level I/O!
+ while (remaining > 0 && ctx->state != SSL_HdskStateGracefulClose)
+ ..what we really have to do is just return as soon as we read one
+ record. A performance hit in the nonblocking case, but that is
+ the only way this code can work in both modes...
+ */
+ if (remaining > 0 && ctx->state != SSL_HdskStateGracefulClose)
+ { assert(ctx->receivedDataBuffer.data == 0);
+ if ((err = SSLReadRecord(rec, ctx)) != 0) {
+ goto exit;
+ }
+ if (rec.contentType == SSL_RecordTypeAppData ||
+ rec.contentType == SSL_RecordTypeV2_0)
+ { if (rec.contents.length <= remaining)
+ { memcpy(charPtr, rec.contents.data, rec.contents.length);
+ remaining -= rec.contents.length;
+ charPtr += rec.contents.length;
+ *processed += rec.contents.length;
+ /* COMPILER BUG!
+ * This:
+ * if ((err = SSLFreeBuffer(rec.contents, ctx)) != 0)
+ * passes the address of rec to SSLFreeBuffer, not the address
+ * of the contents field (which should be offset 8 from the start
+ * of rec).
+ */
+ {
+ SSLBuffer *b = &rec.contents;
+ if ((err = SSLFreeBuffer(*b, ctx)) != 0) {
+ goto exit;
+ }
+ }
+ }
+ else
+ { memcpy(charPtr, rec.contents.data, remaining);
+ charPtr += remaining;
+ *processed += remaining;
+ ctx->receivedDataBuffer = rec.contents;
+ ctx->receivedDataPos = remaining;
+ remaining = 0;
+ }
+ }
+ else {
+ if ((err = SSLProcessProtocolMessage(rec, ctx)) != 0) {
+ goto exit;
+ }
+ if ((err = SSLFreeBuffer(rec.contents, ctx)) != 0) {
+ goto exit;
+ }
+ }
+ }
+
+ err = noErr;
+
+exit:
+ /* shut down on serious errors */
+ switch(err) {
+ case noErr:
+ case errSSLWouldBlock:
+ case errSSLClosedGraceful:
+ case errSSLClosedNoNotify:
+ break;
+ default:
+ sslErrorLog("SSLRead: going to state errorClose due to err %d\n",
+ (int)err);
+ SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
+ break;
+ }
+abort:
+ sslIoTrace("SSLRead ", dataLength, *processed, err);
+ return err;
+}
+
+#if SSL_DEBUG
+#include "appleCdsa.h"
+#endif
+
+OSStatus
+SSLHandshake(SSLContext *ctx)
+{
+ OSStatus err;
+
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if (ctx->state == SSL_HdskStateGracefulClose)
+ return errSSLClosedGraceful;
+ if (ctx->state == SSL_HdskStateErrorClose)
+ return errSSLClosedAbort;
+
+ if(ctx->protocolSide == SSL_ServerSide) {
+ /* some things the caller really has to have done by now... */
+ if((ctx->localCert == NULL) ||
+ (ctx->signingPrivKey == NULL) ||
+ (ctx->signingPubKey == NULL) ||
+ (ctx->signingKeyCsp == 0)) {
+ sslErrorLog("SSLHandshake: insufficient init\n");
+ return badReqErr;
+ }
+ }
+ if(ctx->validCipherSpecs == NULL) {
+ /* build list of legal cipherSpecs */
+ err = sslBuildCipherSpecArray(ctx);
+ if(err) {
+ return err;
+ }
+ }
+ err = noErr;
+ while (ctx->readCipher.ready == 0 || ctx->writeCipher.ready == 0)
+ { if ((err = SSLHandshakeProceed(ctx)) != 0)
+ return err;
+ }
+
+ /* one more flush at completion of successful handshake */
+ if ((err = SSLServiceWriteQueue(ctx)) != 0) {
+ return err;
+ }
+ return noErr;
+}
+
+
+static OSStatus
+SSLHandshakeProceed(SSLContext *ctx)
+{ OSStatus err;
+ SSLRecord rec;
+
+ if (ctx->state == SSL_HdskStateUninit)
+ if ((err = SSLInitConnection(ctx)) != 0)
+ return err;
+ if ((err = SSLServiceWriteQueue(ctx)) != 0)
+ return err;
+ assert(ctx->readCipher.ready == 0);
+ if ((err = SSLReadRecord(rec, ctx)) != 0)
+ return err;
+ if ((err = SSLProcessProtocolMessage(rec, ctx)) != 0)
+ { SSLFreeBuffer(rec.contents, ctx);
+ return err;
+ }
+ if ((err = SSLFreeBuffer(rec.contents, ctx)) != 0)
+ return err;
+
+ return noErr;
+}
+
+static OSStatus
+SSLInitConnection(SSLContext *ctx)
+{ OSStatus err;
+
+ if (ctx->protocolSide == SSL_ClientSide) {
+ SSLChangeHdskState(ctx, SSL_HdskStateClientUninit);
+ }
+ else
+ { assert(ctx->protocolSide == SSL_ServerSide);
+ SSLChangeHdskState(ctx, SSL_HdskStateServerUninit);
+ }
+
+ if (ctx->peerID.data != 0)
+ { SSLGetSessionData(&ctx->resumableSession, ctx);
+ /* Ignore errors; just treat as uncached session */
+ }
+
+ /*
+ * If we have a cached resumable session, blow it off if it's a higher
+ * version than the max currently allowed. Note that this means that once
+ * a process negotiates a given version with a given server/port, it won't
+ * be able to negotiate a higher version. We might want to revisit this.
+ */
+ if (ctx->resumableSession.data != 0) {
+
+ SSLProtocolVersion savedVersion;
+
+ if ((err = SSLRetrieveSessionProtocolVersion(ctx->resumableSession,
+ &savedVersion, ctx)) != 0) {
+ return err;
+ }
+ if(savedVersion > ctx->maxProtocolVersion) {
+ sslLogResumSessDebug("===Resumable session protocol mismatch");
+ SSLFreeBuffer(ctx->resumableSession, ctx);
+ }
+ else {
+ sslLogResumSessDebug("===attempting to resume session");
+ /*
+ * A bit of a special case for server side here. If currently
+ * configged to allow for SSL3/TLS1 with an SSL2 hello, we
+ * don't want to preclude the possiblity of an SSL2 hello...
+ * so we'll just leave the negProtocolVersion alone in the server case.
+ */
+ if(ctx->protocolSide == SSL_ClientSide) {
+ ctx->negProtocolVersion = savedVersion;
+ }
+ }
+ }
+
+ /*
+ * If we're the client & handshake hasn't yet begun, start it by
+ * pretending we just received a hello request
+ */
+ if (ctx->state == SSL_HdskStateClientUninit && ctx->writeCipher.ready == 0)
+ { switch (ctx->negProtocolVersion)
+ { case SSL_Version_Undetermined:
+ case SSL_Version_3_0_With_2_0_Hello:
+ case SSL_Version_2_0:
+ if ((err = SSL2AdvanceHandshake(
+ SSL2_MsgKickstart, ctx)) != 0)
+ return err;
+ break;
+ case SSL_Version_3_0_Only:
+ case SSL_Version_3_0:
+ case TLS_Version_1_0_Only:
+ case TLS_Version_1_0:
+ if ((err = SSLAdvanceHandshake(SSL_HdskHelloRequest, ctx)) != 0)
+ return err;
+ break;
+ default:
+ sslErrorLog("Bad protocol version\n");
+ return errSSLInternal;
+ }
+ }
+
+ return noErr;
+}
+
+static OSStatus
+SSLServiceWriteQueue(SSLContext *ctx)
+{ OSStatus err = noErr, werr = noErr;
+ UInt32 written = 0;
+ SSLBuffer buf, recBuf;
+ WaitingRecord *rec;
+
+ while (!werr && ((rec = ctx->recordWriteQueue) != 0))
+ { buf.data = rec->data.data + rec->sent;
+ buf.length = rec->data.length - rec->sent;
+ werr = sslIoWrite(buf, &written, ctx);
+ rec->sent += written;
+ if (rec->sent >= rec->data.length)
+ { assert(rec->sent == rec->data.length);
+ assert(err == 0);
+ err = SSLFreeBuffer(rec->data, ctx);
+ assert(err == 0);
+ recBuf.data = (UInt8*)rec;
+ recBuf.length = sizeof(WaitingRecord);
+ ctx->recordWriteQueue = rec->next;
+ err = SSLFreeBuffer(recBuf, ctx);
+ assert(err == 0);
+ }
+ if (err)
+ return err;
+ assert(ctx->recordWriteQueue == 0 || ctx->recordWriteQueue->sent == 0);
+ }
+
+ return werr;
+}
+
+static OSStatus
+SSLProcessProtocolMessage(SSLRecord &rec, SSLContext *ctx)
+{ OSStatus err;
+
+ switch (rec.contentType)
+ { case SSL_RecordTypeHandshake:
+ sslLogRxProtocolDebug("Handshake");
+ err = SSLProcessHandshakeRecord(rec, ctx);
+ break;
+ case SSL_RecordTypeAlert:
+ sslLogRxProtocolDebug("Alert");
+ err = SSLProcessAlert(rec, ctx);
+ break;
+ case SSL_RecordTypeChangeCipher:
+ sslLogRxProtocolDebug("ChangeCipher");
+ err = SSLProcessChangeCipherSpec(rec, ctx);
+ break;
+ case SSL_RecordTypeV2_0:
+ sslLogRxProtocolDebug("RecordTypeV2_0");
+ err = SSL2ProcessMessage(rec, ctx);
+ break;
+ default:
+ sslLogRxProtocolDebug("Bad msg");
+ return errSSLProtocol;
+ }
+
+ return err;
+}
+
+OSStatus
+SSLClose(SSLContext *ctx)
+{
+ OSStatus err = noErr;
+
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if (ctx->negProtocolVersion >= SSL_Version_3_0)
+ err = SSLSendAlert(SSL_AlertLevelWarning, SSL_AlertCloseNotify, ctx);
+ if (err == 0)
+ err = SSLServiceWriteQueue(ctx);
+ SSLChangeHdskState(ctx, SSL_HdskStateGracefulClose);
+ if (err == ioErr)
+ err = noErr; /* Ignore errors related to closed streams */
+ return err;
+}
+
+/*
+ * Determine how much data the client can be guaranteed to
+ * obtain via SSLRead() without blocking or causing any low-level
+ * read operations to occur.
+ *
+ * Implemented here because the relevant info in SSLContext (receivedDataBuffer
+ * and receivedDataPos) are only used in this file.
+ */
+OSStatus
+SSLGetBufferedReadSize(SSLContextRef ctx,
+ size_t *bufSize) /* RETURNED */
+{
+ if(ctx == NULL) {
+ return paramErr;
+ }
+ if(ctx->receivedDataBuffer.data == NULL) {
+ *bufSize = 0;
+ }
+ else {
+ assert(ctx->receivedDataBuffer.length >= ctx->receivedDataPos);
+ *bufSize = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
+ }
+ return noErr;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: sslutil.c
+
+ Contains: Misc. SSL utility functions
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "sslUtils.h"
+#include "sslMemory.h"
+#include "sslDebug.h"
+#include <Security/devrandom.h>
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <sys/time.h>
+
+UInt32
+SSLDecodeInt(const unsigned char *p, int length)
+{ UInt32 val = 0;
+ while (length--)
+ val = (val << 8) | *p++;
+ return val;
+}
+
+unsigned char *
+SSLEncodeInt(unsigned char *p, UInt32 value, int length)
+{ unsigned char *retVal = p + length; /* Return pointer to char after int */
+ assert(length > 0 && length <= 4);
+ while (length--) /* Assemble backwards */
+ { p[length] = (UInt8)value; /* Implicit masking to low byte */
+ value >>= 8;
+ }
+ return retVal;
+}
+
+UInt8*
+SSLEncodeUInt64(UInt8 *p, sslUint64 value)
+{ p = SSLEncodeInt(p, value.high, 4);
+ return SSLEncodeInt(p, value.low, 4);
+}
+
+
+void
+IncrementUInt64(sslUint64 *v)
+{ if (++v->low == 0) /* Must have just rolled over */
+ ++v->high;
+}
+
+UInt32
+SSLGetCertificateChainLength(const SSLCertificate *c)
+{
+ UInt32 rtn = 0;
+
+ while (c)
+ {
+ rtn++;
+ c = c->next;
+ }
+ return rtn;
+}
+
+Boolean sslIsSessionActive(const SSLContext *ctx)
+{
+ assert(ctx != NULL);
+ switch(ctx->state) {
+ case SSL_HdskStateUninit:
+ case SSL_HdskStateServerUninit:
+ case SSL_HdskStateClientUninit:
+ case SSL_HdskStateGracefulClose:
+ case SSL_HdskStateErrorClose:
+ return false;
+ default:
+ return true;
+ }
+}
+
+OSStatus sslDeleteCertificateChain(
+ SSLCertificate *certs,
+ SSLContext *ctx)
+{
+ SSLCertificate *cert;
+ SSLCertificate *nextCert;
+
+ assert(ctx != NULL);
+ cert=certs;
+ while(cert != NULL) {
+ nextCert = cert->next;
+ SSLFreeBuffer(cert->derCert, ctx);
+ sslFree(cert);
+ cert = nextCert;
+ }
+ return noErr;
+}
+
+#if SSL_DEBUG
+
+const char *protocolVersStr(SSLProtocolVersion prot)
+{
+ switch(prot) {
+ case SSL_Version_Undetermined: return "SSL_Version_Undetermined";
+ case SSL_Version_3_0_With_2_0_Hello: return "SSL_Version_3_0_With_2_0_Hello";
+ case SSL_Version_3_0_Only: return "SSL_Version_3_0_Only";
+ case SSL_Version_2_0: return "SSL_Version_2_0";
+ case SSL_Version_3_0: return "SSL_Version_3_0";
+ case TLS_Version_1_0: return "TLS_Version_1_0";
+ case TLS_Version_1_0_Only: return "TLS_Version_1_0_Only";
+ default: sslErrorLog("protocolVersStr: bad prot\n"); return "BAD PROTOCOL";
+ }
+ return NULL; /* NOT REACHED */
+}
+
+#endif /* SSL_DEBUG */
+
+/*
+ * Redirect SSLBuffer-based I/O call to user-supplied I/O.
+ */
+OSStatus sslIoRead(
+ SSLBuffer buf,
+ size_t *actualLength,
+ SSLContext *ctx)
+{
+ UInt32 dataLength = buf.length;
+ OSStatus ortn;
+
+ *actualLength = 0;
+ ortn = (ctx->ioCtx.read)(ctx->ioCtx.ioRef,
+ buf.data,
+ &dataLength);
+ *actualLength = dataLength;
+ return ortn;
+}
+
+OSStatus sslIoWrite(
+ SSLBuffer buf,
+ size_t *actualLength,
+ SSLContext *ctx)
+{
+ UInt32 dataLength = buf.length;
+ OSStatus ortn;
+
+ *actualLength = 0;
+ ortn = (ctx->ioCtx.write)(ctx->ioCtx.ioRef,
+ buf.data,
+ &dataLength);
+ *actualLength = dataLength;
+ return ortn;
+}
+
+OSStatus sslTime(UInt32 *tim)
+{
+ time_t t;
+ time(&t);
+ *tim = (UInt32)t;
+ return noErr;
+}
+
+/*
+ * Common RNG function.
+ */
+OSStatus sslRand(SSLContext *ctx, SSLBuffer *buf)
+{
+ OSStatus serr = noErr;
+
+ assert(ctx != NULL);
+ assert(buf != NULL);
+ assert(buf->data != NULL);
+
+ if(buf->length == 0) {
+ sslErrorLog("sslRand: zero buf->length\n");
+ return noErr;
+ }
+ try {
+ Security::DevRandomGenerator devRand(false);
+ devRand.random(buf->data, buf->length);
+ }
+ catch(...) {
+ serr = errSSLCrypto;
+ }
+ return serr;
+}
+
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslalert.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslalert.c Support for alert protocol in SSL 3
-
- Encoding, decoding and processing for the SSL alert protocol. Also,
- support for sending fatal alerts, which also closes down our
- connection, including invalidating our cached session.
-
- ****************************************************************** */
-
-#include "ssl.h"
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLSESS_H_
-#include "sslsess.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#include <assert.h>
-
-SSLErr
-SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
-{ SSLErr err = SSLNoErr;
- AlertLevel level;
- AlertDescription desc;
- uint8 *progress;
- uint32 remaining;
-
- if (rec.contents.length % 2 != 0)
- { ERR(err = SSLFatalSessionAlert(alert_illegal_parameter, ctx));
- if (!err)
- ERR(err = SSLProtocolErr);
- return err;
- }
-
- progress = rec.contents.data;
- remaining = rec.contents.length;
- while (remaining > 0)
- { level = (AlertLevel)*progress++;
- desc = (AlertDescription)*progress++;
- remaining -= 2;
-
- /*
- * APPLE_CDSA changes: ignore sessionID-related failures here;
- * the important thing is the alert.
- */
- if (level == alert_fatal)
- {
- SSLDeleteSessionData(ctx);
- dprintf1("***Fatal alert %d received", desc);
- return SSLFatalAlert;
- }
-
- switch (desc)
- { case alert_unexpected_message:
- case alert_bad_record_mac:
- case alert_decompression_failure:
- case alert_handshake_failure:
- case alert_illegal_parameter:
- /* These must always be fatal; if we got here, the level is warning;
- * die anyway
- */
- SSLDeleteSessionData(ctx);
- err = SSLFatalAlert;
- break;
- case alert_close_notify:
- ERR(SSLClose(ctx));
- err = SSLNoErr;
- break;
- case alert_no_certificate:
- if (ctx->state == HandshakeClientCertificate)
- if (ERR(err = SSLAdvanceHandshake(SSL_certificate, ctx)) != 0)
- return err;
- break;
- case alert_bad_certificate:
- case alert_unsupported_certificate:
- case alert_certificate_revoked:
- case alert_certificate_expired:
- case alert_certificate_unknown:
- err = SSLNoErr;
- break;
- default:
- /* Unknown alert, but not fatal; ignore it */
- break;
- }
- }
-
- return err;
-}
-
-SSLErr
-SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx)
-{ SSLRecord rec;
- SSLErr err;
-
- CASSERT((ctx->negProtocolVersion != SSL_Version_2_0));
-
- if ((err = SSLEncodeAlert(&rec, level, desc, ctx)) != 0)
- return err;
- assert(ctx->sslTslCalls != NULL);
- if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
- return err;
- if ((err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
- return err;
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLEncodeAlert(SSLRecord *rec, AlertLevel level, AlertDescription desc, SSLContext *ctx)
-{ SSLErr err;
-
- rec->contentType = SSL_alert;
- CASSERT((ctx->negProtocolVersion != SSL_Version_2_0));
- if(ctx->negProtocolVersion == SSL_Version_Undetermined) {
- /* error while negotiating */
- rec->protocolVersion = ctx->maxProtocolVersion;
- }
- else {
- rec->protocolVersion = ctx->negProtocolVersion;
- }
- rec->contents.length = 2;
- if ((err = SSLAllocBuffer(&rec->contents, 2, &ctx->sysCtx)) != 0)
- return err;
- rec->contents.data[0] = level;
- rec->contents.data[1] = desc;
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLFatalSessionAlert(AlertDescription desc, SSLContext *ctx)
-{ SSLErr err1, err2;
-
- if(desc != alert_close_notify) {
- errorLog1("SSLFatalSessionAlert: desc %d\n", desc);
- }
- //dprintf0("SSLFatalSessionAlert: going to state ErrorClose\n");
- SSLChangeHdskState(ctx, SSLErrorClose);
-
- /* Make session unresumable; I'm not stopping if I get an error,
- because I'd like to attempt to send the alert anyway */
- err1 = SSLDeleteSessionData(ctx);
-
- /* Second, send the alert */
- err2 = SSLSendAlert(alert_fatal, desc, ctx);
-
- /* If they both returned errors, arbitrarily return the first */
- return err1 != 0 ? err1 : err2;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslalloc.c
-
- Contains: memory allocator implementation
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: sslalloc.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslalloc.c Utility functions for doing allocation
-
- These functions call the user-supplied callbacks to
- allocate/free/reallocate memory
-
- ****************************************************************** */
-
-#include "sslalloc.h"
-#include "sslctx.h"
-#include "sslDebug.h"
-
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
-#pragma mark *** Basic low-level malloc/free ***
-
-/*
- * For now, all allocs/frees go thru here.
- */
-#include <string.h> /* memset */
-#include <stdlib.h>
-
-void *
-sslMalloc(UInt32 length)
-{
- return malloc(length);
-}
-
-void
-sslFree(void *p)
-{
- if(p != nil) {
- free(p);
- }
-}
-
-void *
-sslRealloc(void *oldPtr, UInt32 oldLen, UInt32 newLen)
-{
- return realloc(oldPtr, newLen);
-}
-
-#pragma mark *** SSLBuffer-level alloc/free ***
-
-SSLErr SSLAllocBuffer(
- SSLBuffer *buf,
- UInt32 length,
- const SystemContext *ctx)
-{
- buf->data = sslMalloc(length);
- if(buf->data == NULL) {
- buf->length = 0;
- return SSLMemoryErr;
- }
- buf->length = length;
- return SSLNoErr;
-}
-
-SSLErr
-SSLFreeBuffer(SSLBuffer *buf, const SystemContext *ctx)
-{
- if(buf == NULL) {
- errorLog0("SSLFreeBuffer: NULL buf!\n");
- return SSLInternalError;
- }
- sslFree(buf->data);
- buf->data = NULL;
- buf->length = 0;
- return SSLNoErr;
-}
-
-SSLErr
-SSLReallocBuffer(SSLBuffer *buf, UInt32 newSize, const SystemContext *ctx)
-{
- buf->data = sslRealloc(buf->data, buf->length, newSize);
- if(buf->data == NULL) {
- buf->length = 0;
- return SSLMemoryErr;
- }
- buf->length = newSize;
- return SSLNoErr;
-}
-
-#pragma mark *** Convenience routines ***
-
-UInt8 *sslAllocCopy(
- const UInt8 *src,
- UInt32 len)
-{
- UInt8 *dst;
-
- dst = sslMalloc(len);
- if(dst == NULL) {
- return NULL;
- }
- memmove(dst, src, len);
- return dst;
-}
-
-SSLErr SSLAllocCopyBuffer(
- const SSLBuffer *src,
- SSLBuffer **dst) // buffer and data mallocd and returned
-{
- SSLErr serr;
-
- SSLBuffer *rtn = sslMalloc(sizeof(SSLBuffer));
- if(rtn == NULL) {
- return SSLMemoryErr;
- }
- serr = SSLCopyBuffer(src, rtn);
- if(serr) {
- sslFree(rtn);
- }
- else {
- *dst = rtn;
- }
- return serr;
-}
-
-SSLErr SSLCopyBuffer(
- const SSLBuffer *src,
- SSLBuffer *dst) // data mallocd and returned
-{
- dst->data = sslAllocCopy(src->data, src->length);
- if(dst->data == NULL) {
- return SSLMemoryErr;
- }
- dst->length = src->length;
- return SSLNoErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslctx.c
-
- Contains: SSLContext accessors
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: sslctx.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslctx.c SSLContext accessors
-
- Functions called by the end user which configure an SSLContext
- structure or access data stored there.
-
- ****************************************************************** */
-
-
-#include "ssl.h"
-#include "sslctx.h"
-#include "sslalloc.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-#include "digests.h"
-#include "sslDebug.h"
-#include "appleCdsa.h"
-#include "appleGlue.h"
-#include "sslKeychain.h"
-#include "sslutil.h"
-#include "cipherSpecs.h"
-#include "appleSession.h"
-#include <string.h>
-#include <Security/SecCertificate.h>
-
-static void sslFreeDnList(
- SSLContext *ctx)
-{
- DNListElem *dn, *nextDN;
- SSLBuffer buf;
-
- dn = ctx->acceptableDNList;
-
- while (dn)
- {
- SSLFreeBuffer(&dn->derDN, &ctx->sysCtx);
- nextDN = dn->next;
- buf.data = (uint8*)dn;
- buf.length = sizeof(DNListElem);
- SSLFreeBuffer(&buf, &ctx->sysCtx);
- dn = nextDN;
- }
- ctx->acceptableDNList = NULL;
-}
-
-static SSLErr sslFreeTrustedRoots(
- SSLContext *ctx)
-{
- int i;
-
- CASSERT(ctx != NULL);
- if((ctx->numTrustedCerts == 0) || (ctx->trustedCerts == NULL)) {
- /* they really should both be zero, right? */
- CASSERT((ctx->numTrustedCerts == 0) && (ctx->trustedCerts == NULL));
- }
- else {
- for(i=0; i<ctx->numTrustedCerts; i++) {
- stFreeCssmData(&ctx->trustedCerts[i], CSSM_FALSE);
- }
- sslFree(ctx->trustedCerts);
- }
- ctx->numTrustedCerts = 0;
- ctx->trustedCerts = NULL;
- sslFreeDnList(ctx);
- return SSLNoErr;
-}
-
-/*
- * Default attempted version.
- */
-#define DEFAULT_MAX_VERSION TLS_Version_1_0
-
-OSStatus
-SSLNewContext (Boolean isServer,
- SSLContextRef *contextPtr) /* RETURNED */
-{
- SSLContext *ctx;
- OSStatus oerr;
- SSLErr serr;
-
- if(contextPtr == NULL) {
- return paramErr;
- }
- *contextPtr = NULL;
- ctx = (SSLContext *)sslMalloc(sizeof(SSLContext));
- if(ctx == NULL) {
- return memFullErr;
- }
- /* subsequent errors to errOut: */
-
- memset(ctx, 0, sizeof(SSLContext));
- ctx->state = SSLUninitialized;
-
- /* different defaults for client and server ... */
- if(isServer) {
- ctx->protocolSide = SSL_ServerSide;
- ctx->reqProtocolVersion = DEFAULT_MAX_VERSION;
- }
- else {
- ctx->protocolSide = SSL_ClientSide;
- ctx->reqProtocolVersion = SSL_Version_Undetermined;
- }
- ctx->negProtocolVersion = SSL_Version_Undetermined;
- ctx->maxProtocolVersion = DEFAULT_MAX_VERSION;
- /* Default value so we can send and receive hello msgs */
- ctx->sslTslCalls = &Ssl3Callouts;
-
- /* Initialize the cipher state to NULL_WITH_NULL_NULL */
- ctx->selectedCipherSpec = &SSL_NULL_WITH_NULL_NULL_CipherSpec;
- ctx->selectedCipher = ctx->selectedCipherSpec->cipherSpec;
- ctx->writeCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
- ctx->readCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
- ctx->readCipher.symCipher = ctx->selectedCipherSpec->cipher;
- ctx->writeCipher.symCipher = ctx->selectedCipherSpec->cipher;
-
- /* these two are invariant */
- ctx->writeCipher.encrypting = 1;
- ctx->writePending.encrypting = 1;
-
- /* this gets init'd on first call to SSLHandshake() */
- ctx->validCipherSpecs = NULL;
- ctx->numValidCipherSpecs = 0;
-
- ctx->peerDomainName = NULL;
- ctx->peerDomainNameLen = 0;
-
- SSLInitMACPads();
-
- /* attach to CSP, CL, TP */
- serr = attachToAll(ctx);
- if(serr) {
- oerr = sslErrToOsStatus(serr);
- goto errOut;
- }
-
- /* snag root certs from Keychain, tolerate error */
- addBuiltInCerts(ctx);
-
- *contextPtr = ctx;
- return noErr;
-
-errOut:
- sslFree(ctx);
- return oerr;
-}
-
-
-/*
- * Dispose of an SSLContext.
- */
-OSStatus
-SSLDisposeContext (SSLContext *ctx)
-{
- WaitingRecord *wait, *next;
- SSLBuffer buf;
-
- if(ctx == NULL) {
- return paramErr;
- }
- sslDeleteCertificateChain(ctx->localCert, ctx);
- sslDeleteCertificateChain(ctx->encryptCert, ctx);
- sslDeleteCertificateChain(ctx->peerCert, ctx);
- ctx->localCert = ctx->encryptCert = ctx->peerCert = NULL;
- SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx);
-
- wait = ctx->recordWriteQueue;
- while (wait)
- { SSLFreeBuffer(&wait->data, &ctx->sysCtx);
- next = wait->next;
- buf.data = (uint8*)wait;
- buf.length = sizeof(WaitingRecord);
- SSLFreeBuffer(&buf, &ctx->sysCtx);
- wait = next;
- }
-
- SSLFreeBuffer(&ctx->dhPeerPublic, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->dhExchangePublic, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->dhPrivate, &ctx->sysCtx);
-
- CloseHash(&SSLHashSHA1, &ctx->shaState, ctx);
- CloseHash(&SSLHashMD5, &ctx->md5State, ctx);
-
- SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->peerID, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->resumableSession, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->fragmentedMessageCache, &ctx->sysCtx);
- SSLFreeBuffer(&ctx->receivedDataBuffer, &ctx->sysCtx);
-
- if(ctx->peerDomainName) {
- sslFree(ctx->peerDomainName);
- ctx->peerDomainName = NULL;
- ctx->peerDomainNameLen = 0;
- }
- SSLDisposeCipherSuite(&ctx->readCipher, ctx);
- SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
- SSLDisposeCipherSuite(&ctx->readPending, ctx);
- SSLDisposeCipherSuite(&ctx->writePending, ctx);
-
- sslFree(ctx->validCipherSpecs);
- ctx->validCipherSpecs = NULL;
- ctx->numValidCipherSpecs = 0;
-
- /* free APPLE_CDSA stuff */
- #if 0
- /* As of 5/3/02, we don't need to free these keys; they belong
- * to SecKeychain */
- #if ST_KEYCHAIN_ENABLE && ST_KC_KEYS_NEED_REF
- sslFreeKey(ctx->signingKeyCsp, &ctx->signingPrivKey, &ctx->signingKeyRef);
- sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPrivKey, &ctx->encryptKeyRef);
- #else
- sslFreeKey(ctx->signingKeyCsp, (CSSM_KEY_PTR *)&ctx->signingPrivKey, NULL);
- sslFreeKey(ctx->encryptKeyCsp, (CSSM_KEY_PTR *)&ctx->encryptPrivKey, NULL);
- #endif /* ST_KEYCHAIN_ENABLE && ST_KC_KEYS_NEED_REF */
- #endif /* 0 */
-
- /*
- * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
- * We really don't know what CSP the CL used to generate a public key (in fact,
- * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
- * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
- * signingPubKey is not tecnically accurate. However, our public keys
- * are all raw keys, and all Apple CSPs dispose of raw keys in the same
- * way.
- */
- sslFreeKey(ctx->signingKeyCsp, &ctx->signingPubKey, NULL);
- sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPubKey, NULL);
- sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
-
- #if SSL_DEBUG
- if(ctx->rootCertName != NULL) {
- sslFree(ctx->rootCertName);
- }
- #endif /* SSL_DEBUG */
-
- sslFreeTrustedRoots(ctx);
-
- detachFromAll(ctx);
-
- memset(ctx, 0, sizeof(SSLContext));
- sslFree(ctx);
- sslCleanupSession();
- return noErr;
-}
-
-/*
- * Determine the state of an SSL session.
- */
-OSStatus
-SSLGetSessionState (SSLContextRef context,
- SSLSessionState *state) /* RETURNED */
-{
- SSLSessionState rtnState = kSSLIdle;
-
- if(context == NULL) {
- return paramErr;
- }
- *state = rtnState;
- switch(context->state) {
- case SSLUninitialized:
- case HandshakeServerUninit:
- case HandshakeClientUninit:
- rtnState = kSSLIdle;
- break;
- case SSLGracefulClose:
- rtnState = kSSLClosed;
- break;
- case SSLErrorClose:
- case SSLNoNotifyClose:
- rtnState = kSSLAborted;
- break;
- case HandshakeServerReady:
- case HandshakeClientReady:
- rtnState = kSSLConnected;
- break;
- default:
- CASSERT((context->state >= HandshakeServerHello) &&
- (context->state <= HandshakeSSL2ServerFinished));
- rtnState = kSSLHandshake;
- break;
-
- }
- *state = rtnState;
- return noErr;
-}
-
-OSStatus
-SSLSetIOFuncs (SSLContextRef ctx,
- SSLReadFunc read,
- SSLWriteFunc write)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- ctx->ioCtx.read = read;
- ctx->ioCtx.write = write;
- return noErr;
-}
-
-OSStatus
-SSLSetConnection (SSLContextRef ctx,
- SSLConnectionRef connection)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- ctx->ioCtx.ioRef = connection;
- return noErr;
-}
-
-OSStatus
-SSLSetPeerDomainName (SSLContextRef ctx,
- const char *peerName,
- size_t peerNameLen)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
-
- /* free possible existing name */
- if(ctx->peerDomainName) {
- sslFree(ctx->peerDomainName);
- }
-
- /* copy in */
- ctx->peerDomainName = sslMalloc(peerNameLen);
- if(ctx->peerDomainName == NULL) {
- return memFullErr;
- }
- memmove(ctx->peerDomainName, peerName, peerNameLen);
- ctx->peerDomainNameLen = peerNameLen;
- return noErr;
-}
-
-/*
- * Determine the buffer size needed for SSLGetPeerDomainName().
- */
-OSStatus
-SSLGetPeerDomainNameLength (SSLContextRef ctx,
- size_t *peerNameLen) // RETURNED
-{
- if(ctx == NULL) {
- return paramErr;
- }
- *peerNameLen = ctx->peerDomainNameLen;
- return noErr;
-}
-
-OSStatus
-SSLGetPeerDomainName (SSLContextRef ctx,
- char *peerName, // returned here
- size_t *peerNameLen) // IN/OUT
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(*peerNameLen < ctx->peerDomainNameLen) {
- return errSSLBufferOverflow;
- }
- memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
- *peerNameLen = ctx->peerDomainNameLen;
- return noErr;
-}
-
-OSStatus
-SSLSetProtocolVersion (SSLContextRef ctx,
- SSLProtocol version)
-{
- SSLProtocolVersion versInt;
- SSLProtocolVersion versMax;
-
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
-
- /* convert external representation to private */
- switch(version) {
- case kSSLProtocolUnknown:
- versInt = SSL_Version_Undetermined;
- versMax = DEFAULT_MAX_VERSION;
- break;
- case kSSLProtocol2:
- versInt = versMax = SSL_Version_2_0;
- break;
- case kSSLProtocol3:
- /* this tells us to do our best but allows 2.0 */
- versInt = SSL_Version_Undetermined;
- versMax = SSL_Version_3_0;
- break;
- case kSSLProtocol3Only:
- versInt = SSL_Version_3_0_Only;
- versMax = SSL_Version_3_0;
- break;
- case kTLSProtocol1:
- /* this tells us to do our best but allows 2.0 */
- versInt = SSL_Version_Undetermined;
- versMax = TLS_Version_1_0;
- break;
- case kTLSProtocol1Only:
- versInt = TLS_Version_1_0_Only;
- versMax = TLS_Version_1_0;
- break;
- default:
- return paramErr;
- }
- ctx->reqProtocolVersion = ctx->negProtocolVersion = versInt;
- ctx->maxProtocolVersion = versMax;
- return noErr;
-}
-
-static SSLProtocol convertProtToExtern(SSLProtocolVersion prot)
-{
- switch(prot) {
- case SSL_Version_Undetermined:
- return kSSLProtocolUnknown;
- case SSL_Version_3_0_Only:
- return kSSLProtocol3Only;
- case SSL_Version_2_0:
- return kSSLProtocol2;
- case SSL_Version_3_0:
- return kSSLProtocol3;
- case TLS_Version_1_0_Only:
- return kTLSProtocol1Only;
- case TLS_Version_1_0:
- return kTLSProtocol1;
- /* this can happen in an intermediate state while negotiation
- * is in progress...right? */
- case SSL_Version_3_0_With_2_0_Hello:
- return kSSLProtocolUnknown;
- default:
- sslPanic("convertProtToExtern: bad prot");
- }
- /* not reached but make compiler happy */
- return kSSLProtocolUnknown;
-}
-
-OSStatus
-SSLGetProtocolVersion (SSLContextRef ctx,
- SSLProtocol *protocol) /* RETURNED */
-{
- if(ctx == NULL) {
- return paramErr;
- }
- *protocol = convertProtToExtern(ctx->reqProtocolVersion);
- return noErr;
-}
-
-OSStatus
-SSLGetNegotiatedProtocolVersion (SSLContextRef ctx,
- SSLProtocol *protocol) /* RETURNED */
-{
- if(ctx == NULL) {
- return paramErr;
- }
- *protocol = convertProtToExtern(ctx->negProtocolVersion);
- return noErr;
-}
-
-OSStatus
-SSLSetAllowsExpiredCerts(SSLContextRef ctx,
- Boolean allowExpired)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- ctx->allowExpiredCerts = allowExpired;
- return noErr;
-}
-
-OSStatus
-SSLGetAllowsExpiredCerts (SSLContextRef ctx,
- Boolean *allowExpired)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- *allowExpired = ctx->allowExpiredCerts;
- return noErr;
-}
-
-OSStatus SSLSetAllowsAnyRoot(
- SSLContextRef ctx,
- Boolean anyRoot)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- ctx->allowAnyRoot = anyRoot;
- return noErr;
-}
-
-OSStatus
-SSLGetAllowsAnyRoot(
- SSLContextRef ctx,
- Boolean *anyRoot)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- *anyRoot = ctx->allowAnyRoot;
- return noErr;
-}
-
-#if ST_SERVER_MODE_ENABLE
-OSStatus
-SSLSetClientSideAuthenticate (SSLContext *ctx,
- SSLAuthenticate auth)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- ctx->clientAuth = auth;
- switch(auth) {
- case kNeverAuthenticate:
- ctx->tryClientAuth = false;
- break;
- case kAlwaysAuthenticate:
- case kTryAuthenticate:
- /* FIXME - needs work to distinguish these cases at
- * handshake time */
- ctx->tryClientAuth = true;
- break;
- }
- return noErr;
-}
-#endif /* ST_SERVER_MODE_ENABLE */
-
-#if (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
-
-OSStatus
-SSLSetCertificate (SSLContextRef ctx,
- CFArrayRef certRefs)
-{
- /*
- * -- free localCerts if we have any
- * -- Get raw cert data, convert to ctx->localCert
- * -- get pub, priv keys from certRef[0]
- * -- validate cert chain
- */
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- return parseIncomingCerts(ctx,
- certRefs,
- &ctx->localCert,
- &ctx->signingPubKey,
- &ctx->signingPrivKey,
- &ctx->signingKeyCsp
- #if ST_KC_KEYS_NEED_REF
- ,
- &ctx->signingKeyRef
- #else
- );
- #endif
-}
-#endif /* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
-
-#if ST_SERVER_MODE_ENABLE
-OSStatus
-SSLSetEncryptionCertificate (SSLContextRef ctx,
- CFArrayRef certRefs)
-{
- /*
- * -- free encryptCert if we have any
- * -- Get raw cert data, convert to ctx->encryptCert
- * -- get pub, priv keys from certRef[0]
- * -- validate cert chain
- */
- if(ctx == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- return parseIncomingCerts(ctx,
- certRefs,
- &ctx->encryptCert,
- &ctx->encryptPubKey,
- &ctx->encryptPrivKey,
- &ctx->encryptKeyCsp
- #if ST_KC_KEYS_NEED_REF
- ,
- &ctx->encryptKeyRef);
- #else
- );
- #endif
-}
-#endif /* ST_SERVER_MODE_ENABLE*/
-
-#if ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS
-
-/*
- * Add (optional, additional) trusted root certs.
- */
-OSStatus
-SSLSetTrustedRootCertKC (SSLContextRef ctx,
- KCRef keyChainRef,
- Boolean deleteExisting)
-{
- /*
- * -- free trustedCerts if deleteExisting
- * -- Get raw cert data, add to ctx->trustedCerts
- * -- verify that each of these is a valid (self-verifying)
- * root cert
- * -- add each subject name to acceptableDNList
- */
- if((ctx == NULL) || (keyChainRef == nil)) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- if(deleteExisting) {
- sslFreeTrustedRoots(ctx);
- }
- return parseTrustedKeychain(ctx, keyChainRef);
-}
-
-OSStatus
-SSLSetNewRootKC (SSLContextRef ctx,
- KCRef keyChainRef,
- void *accessCreds)
-{
- if((ctx == NULL) || (keyChainRef == nil)) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- if(ctx->newRootCertKc != NULL) {
- /* can't do this multiple times */
- return badReqErr;
- }
- ctx->newRootCertKc = keyChainRef;
- ctx->accessCreds = accessCreds;
- return noErr;
-}
-#endif /* ST_KEYCHAIN_ENABLE && ST_MANAGES_TRUSTED_ROOTS */
-
-OSStatus
-SSLSetPeerID (SSLContext *ctx,
- const void *peerID,
- size_t peerIDLen)
-{
- SSLErr serr;
-
- /* copy peerId to context->peerId */
- if((ctx == NULL) ||
- (peerID == NULL) ||
- (peerIDLen == 0)) {
- return paramErr;
- }
- if(sslIsSessionActive(ctx)) {
- /* can't do this with an active session */
- return badReqErr;
- }
- SSLFreeBuffer(&ctx->peerID, &ctx->sysCtx);
- serr = SSLAllocBuffer(&ctx->peerID, peerIDLen, &ctx->sysCtx);
- if(serr) {
- return sslErrToOsStatus(serr);
- }
- memmove(ctx->peerID.data, peerID, peerIDLen);
- return noErr;
-}
-
-OSStatus
-SSLGetPeerID (SSLContextRef ctx,
- const void **peerID,
- size_t *peerIDLen)
-{
- *peerID = ctx->peerID.data; // may be NULL
- *peerIDLen = ctx->peerID.length;
- return noErr;
-}
-
-OSStatus
-SSLGetNegotiatedCipher (SSLContextRef ctx,
- SSLCipherSuite *cipherSuite)
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(!sslIsSessionActive(ctx)) {
- return badReqErr;
- }
- *cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
- return noErr;
-}
-
-/*
- * Add an acceptable distinguished name.
- * FIXME - this looks like a big hole in the SSLRef code;
- * acceptableDNList is set here and in SSLProcessCertificateRequest();
- * it's used and sent to a client in SSLEncodeCertificateRequest();
- * but the list is never used to decide what certs to send!
- *
- * Also FIXME - this allocation of dnBufs is preposterous. The
- * SSLBufs can never get freed. Why not just allocate the
- * raw DNListElems? Sheesh.
- */
-#if 0
-/* not used */
-static SSLErr
-SSLAddDistinguishedName(SSLContext *ctx, SSLBuffer derDN)
-{ SSLBuffer dnBuf;
- DNListElem *dn;
- SSLErr err;
-
- if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem), &ctx->sysCtx)) != 0)
- return err;
- dn = (DNListElem*)dnBuf.data;
- if ((err = SSLAllocBuffer(&dn->derDN, derDN.length, &ctx->sysCtx)) != 0)
- { SSLFreeBuffer(&dnBuf, &ctx->sysCtx);
- return err;
- }
- memcpy(dn->derDN.data, derDN.data, derDN.length);
- dn->next = ctx->acceptableDNList;
- ctx->acceptableDNList = dn;
- return SSLNoErr;
-}
-#endif /* not used */
-
-/*
- * Request peer certificates. Valid anytime, subsequent to
- * a handshake attempt.
- */
-OSStatus
-SSLGetPeerCertificates (SSLContextRef ctx,
- CFArrayRef *certs)
-{
- uint32 numCerts;
- CFMutableArrayRef ca;
- CFIndex i;
- SecCertificateRef cfd;
- OSStatus ortn;
- CSSM_DATA certData;
- SSLCertificate *scert;
-
- if(ctx == NULL) {
- return paramErr;
- }
- *certs = NULL;
-
- /*
- * Copy peerCert, a chain of SSLCertificates, to a CFArray of
- * CFDataRefs, each of which is one DER-encoded cert.
- */
- numCerts = SSLGetCertificateChainLength(ctx->peerCert);
- if(numCerts == 0) {
- return noErr;
- }
- ca = CFArrayCreateMutable(kCFAllocatorDefault,
- (CFIndex)numCerts, &kCFTypeArrayCallBacks);
- if(ca == NULL) {
- return memFullErr;
- }
-
- /*
- * Caller gets leaf cert first, the opposite of the way we store them.
- */
- scert = ctx->peerCert;
- for(i=0; i<numCerts; i++) {
- CASSERT(scert != NULL); /* else SSLGetCertificateChainLength
- * broken */
- SSLBUF_TO_CSSM(&scert->derCert, &certData);
- ortn = SecCertificateCreateFromData(&certData,
- CSSM_CERT_X_509v3,
- CSSM_CERT_ENCODING_DER,
- &cfd);
- if(ortn) {
- CFRelease(ca);
- return ortn;
- }
- /* insert at head of array */
- CFArrayInsertValueAtIndex(ca, 0, cfd);
- scert = scert->next;
- }
- *certs = ca;
- return noErr;
-}
-
-
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslhdshk.c
-
- Contains: SSL 3.0 handshake state machine.
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: sslhdshk.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslhdshk.c SSL 3.0 handshake state machine
-
- Support for SSL Handshake messages, including extracting handshake
- messages from record layer records, processing those messages
- (including verifying their appropriateness) and then advancing the
- handshake by generating response messages and/or changing the state
- such that different messages are expected. In addition, controls when
- keys are generated.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLHDSHK_H_
-#include "sslhdshk.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSLSESS_H_
-#include "sslsess.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _APPLE_CDSA_H_
-#include "appleCdsa.h"
-#endif
-
-#include "digests.h"
-#include <string.h>
-#include <assert.h>
-
-#define REQUEST_CERT_CORRECT 0
-
-static SSLErr SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
-
-SSLErr
-SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
-{ SSLErr err;
- sint32 remaining;
- UInt8 *p;
- SSLHandshakeMsg message;
- SSLBuffer messageData;
-
- if (ctx->fragmentedMessageCache.data != 0)
- { if ((err = SSLReallocBuffer(&ctx->fragmentedMessageCache,
- ctx->fragmentedMessageCache.length + rec.contents.length,
- &ctx->sysCtx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return ERR(err);
- }
- memcpy(ctx->fragmentedMessageCache.data + ctx->fragmentedMessageCache.length,
- rec.contents.data, rec.contents.length);
- remaining = ctx->fragmentedMessageCache.length;
- p = ctx->fragmentedMessageCache.data;
- }
- else
- { remaining = rec.contents.length;
- p = rec.contents.data;
- }
-
- while (remaining > 0)
- { if (remaining < 4)
- break; /* we must have at least a header */
-
- messageData.data = p;
- message.type = (SSLHandshakeType)*p++;
- message.contents.length = SSLDecodeInt(p, 3);
- if ((message.contents.length + 4) > remaining)
- break;
-
- p += 3;
- message.contents.data = p;
- p += message.contents.length;
- messageData.length = 4 + message.contents.length;
- CASSERT(p == messageData.data + messageData.length);
-
- /* message fragmentation */
- remaining -= messageData.length;
- if (ERR(err = SSLProcessHandshakeMessage(message, ctx)) != 0)
- return err;
-
- if (message.type != SSL_hello_request)
- { if (ERR(err = SSLHashSHA1.update(ctx->shaState, messageData)) != 0 ||
- ERR(err = SSLHashMD5.update(ctx->md5State, messageData)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- }
-
- if (ERR(err = SSLAdvanceHandshake(message.type, ctx)) != 0)
- return err;
- }
-
- if (remaining > 0) /* Fragmented handshake message */
- { /* If there isn't a cache, allocate one */
- if (ctx->fragmentedMessageCache.data == 0)
- { if (ERR(err = SSLAllocBuffer(&ctx->fragmentedMessageCache, remaining, &ctx->sysCtx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- }
- if (p != ctx->fragmentedMessageCache.data)
- { memcpy(ctx->fragmentedMessageCache.data, p, remaining);
- ctx->fragmentedMessageCache.length = remaining;
- }
- }
- else if (ctx->fragmentedMessageCache.data != 0)
- { if (ERR(err = SSLFreeBuffer(&ctx->fragmentedMessageCache, &ctx->sysCtx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- }
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
-{ SSLErr err;
-
- err = SSLNoErr;
- SSLLogHdskMsg(message.type, 0);
- switch (message.type)
- { case SSL_hello_request:
- if (ctx->protocolSide != SSL_ClientSide)
- goto wrongMessage;
- if (message.contents.length > 0)
- err = ERR(SSLProtocolErr);
- break;
- case SSL_client_hello:
- if (ctx->state != HandshakeServerUninit)
- goto wrongMessage;
- ERR(err = SSLProcessClientHello(message.contents, ctx));
- break;
- case SSL_server_hello:
- if (ctx->state != HandshakeServerHello &&
- ctx->state != HandshakeServerHelloUnknownVersion)
- goto wrongMessage;
- ERR(err = SSLProcessServerHello(message.contents, ctx));
- break;
- case SSL_certificate:
- if (ctx->state != HandshakeCertificate &&
- ctx->state != HandshakeClientCertificate)
- goto wrongMessage;
- ERR(err = SSLProcessCertificate(message.contents, ctx));
- break;
- case SSL_certificate_request:
- if ((ctx->state != HandshakeHelloDone && ctx->state != HandshakeKeyExchange)
- || ctx->certRequested)
- goto wrongMessage;
- ERR(err = SSLProcessCertificateRequest(message.contents, ctx));
- break;
- case SSL_server_key_exchange:
- /*
- * Since this message is optional, and completely at the
- * server's discretion, we need to be able to handle this
- * in one of two states...
- */
- switch(ctx->state) {
- case HandshakeKeyExchange: /* explicitly waiting for this */
- case HandshakeHelloDone:
- break;
- default:
- goto wrongMessage;
- }
- ERR(err = SSLProcessServerKeyExchange(message.contents, ctx));
- break;
- case SSL_server_hello_done:
- if (ctx->state != HandshakeHelloDone)
- goto wrongMessage;
- ERR(err = SSLProcessServerHelloDone(message.contents, ctx));
- break;
- case SSL_certificate_verify:
- if (ctx->state != HandshakeClientCertVerify)
- goto wrongMessage;
- ERR(err = SSLProcessCertificateVerify(message.contents, ctx));
- break;
- case SSL_client_key_exchange:
- if (ctx->state != HandshakeClientKeyExchange)
- goto wrongMessage;
- ERR(err = SSLProcessKeyExchange(message.contents, ctx));
- break;
- case SSL_finished:
- if (ctx->state != HandshakeFinished)
- goto wrongMessage;
- ERR(err = SSLProcessFinished(message.contents, ctx));
- break;
- default:
- goto wrongMessage;
- break;
- }
-
- if (err)
- { if (err == SSLProtocolErr)
- ERR(SSLFatalSessionAlert(alert_illegal_parameter, ctx));
- else if (err == SSLNegotiationErr)
- ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
- else
- ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- }
- return ERR(err);
-
-wrongMessage:
- ERR(SSLFatalSessionAlert(alert_unexpected_message, ctx));
- return ERR(SSLProtocolErr);
-}
-
-SSLErr
-SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
-{ SSLErr err;
- SSLBuffer sessionIdentifier;
-
- switch (processed)
- { case SSL_hello_request:
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
- return err;
- SSLChangeHdskState(ctx, HandshakeServerHello);
- break;
- case SSL_client_hello:
- CASSERT(ctx->protocolSide == SSL_ServerSide);
- if (ctx->sessionID.data != 0) /* If session ID != 0, client is trying to resume */
- { if (ctx->resumableSession.data != 0)
- { if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
- return err;
- if (sessionIdentifier.length == ctx->sessionID.length &&
- memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
- { /* Everything matches; resume the session */
- //DEBUGMSG("Using resumed SSL3 Session");
- SSLLogResumSess("===RESUMING SSL3 server-side session\n");
- if (ERR(err = SSLInstallSessionFromData(ctx->resumableSession,
- ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
- return err;
- if (ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
- ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
- return err;
- /* Install new cipher spec on write side */
- if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- ctx->writeCipher = ctx->writePending;
- ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
- memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
- return err;
- /* Finished has been sent; enable data dransfer on write channel */
- ctx->writeCipher.ready = 1;
- SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
- break;
- }
- else {
- SSLLogResumSess(
- "===FAILED TO RESUME SSL3 server-side session\n");
- }
- if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0 ||
- ERR(err = SSLDeleteSessionData(ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- }
- if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- }
-
- /* If we get here, we're not resuming; generate a new session ID if we know our peer */
- if (ctx->peerID.data != 0)
- { /* Ignore errors; just treat as uncached session */
- CASSERT(ctx->sessionID.data == 0);
- ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx));
- if (err == 0)
- {
- if((err = sslRand(ctx, &ctx->sessionID)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- }
- }
-
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
- return err;
- switch (ctx->selectedCipherSpec->keyExchangeMethod)
- { case SSL_NULL_auth:
- #if APPLE_DH
- case SSL_DH_anon:
- #endif
- case SSL_DH_anon_EXPORT:
- #if ST_SERVER_MODE_ENABLE
- if(ctx->clientAuth == kAlwaysAuthenticate) {
- /* APPLE_CDSA change: app requires this; abort */
- SSLFatalSessionAlert(alert_handshake_failure, ctx);
- return SSLNegotiationErr;
- }
- ctx->tryClientAuth = false;
- #else /* ST_SERVER_MODE_ENABLE */
- /* server side needs work */
- #endif /* ST_SERVER_MODE_ENABLE*/
- break;
- default: /* everything else */
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
- return err;
- break;
- }
- /*
- * At this point we decide whether to send a server key exchange
- * method. For Apple servers, I think we'll ALWAYS do this, because
- * of key usage restrictions (can't decrypt and sign with the same
- * private key), but conceptually in this code, we do it if
- * enabled by the presence of encryptPrivKey.
- */
- #if SSL_SERVER_KEYEXCH_HACK
- /*
- * This is currently how we work with Netscape. It requires
- * a CSP which can handle private keys which can both
- * sign and decrypt.
- */
- if((ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA) &&
- (ctx->encryptPrivKey != NULL)) {
- err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
- if(err) {
- return err;
- }
- }
- #else /* !SSL_SERVER_KEYEXCH_HACK */
- /*
- * This is, I believe the "right" way, but Netscape doesn't
- * work this way.
- */
- if (ctx->encryptPrivKey != NULL) {
- err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
- if(err) {
- return err;
- }
- }
- #endif /* SSL_SERVER_KEYEXCH_HACK */
-
- #if ST_SERVER_MODE_ENABLE
- if (ctx->tryClientAuth)
- { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest, ctx)) != 0)
- return err;
- ctx->certRequested = 1;
- }
- #else /* !ST_SERVER_MODE_ENABLE */
- /* disabled for now */
- #endif /* ST_SERVER_MODE_ENABLE */
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
- return err;
- if (ctx->certRequested) {
- SSLChangeHdskState(ctx, HandshakeClientCertificate);
- }
- else {
- SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
- }
- break;
- case SSL_server_hello:
- if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
- { if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- if (sessionIdentifier.length == ctx->sessionID.length &&
- memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
- { /* Everything matches; resume the session */
- SSLLogResumSess("===RESUMING SSL3 client-side session\n");
- if (ERR(err = SSLInstallSessionFromData(ctx->resumableSession,
- ctx)) != 0 ||
- ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
- ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
- break;
- }
- else {
- SSLLogResumSess("===FAILED TO RESUME SSL3 client-side session\n");
- }
- if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- }
- switch (ctx->selectedCipherSpec->keyExchangeMethod)
- {
- /* these require a key exchange message */
- case SSL_NULL_auth:
- case SSL_DH_anon:
- case SSL_DH_anon_EXPORT:
- SSLChangeHdskState(ctx, HandshakeKeyExchange);
- break;
- case SSL_RSA:
- case SSL_DH_DSS:
- case SSL_DH_DSS_EXPORT:
- case SSL_DH_RSA:
- case SSL_DH_RSA_EXPORT:
- case SSL_RSA_EXPORT:
- case SSL_DHE_DSS:
- case SSL_DHE_DSS_EXPORT:
- case SSL_DHE_RSA:
- case SSL_DHE_RSA_EXPORT:
- case SSL_Fortezza:
- SSLChangeHdskState(ctx, HandshakeCertificate);
- break;
- default:
- ASSERTMSG("Unknown key exchange method");
- break;
- }
- break;
- case SSL_certificate:
- if (ctx->state == HandshakeCertificate)
- switch (ctx->selectedCipherSpec->keyExchangeMethod)
- { case SSL_RSA:
- /*
- * I really think the two RSA cases should be
- * handled the same here - the server key exchange is
- * optional, and is up to the server.
- * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
- * we're a client here.
- */
- case SSL_RSA_EXPORT:
- case SSL_DH_DSS:
- case SSL_DH_DSS_EXPORT:
- case SSL_DH_RSA:
- case SSL_DH_RSA_EXPORT:
- SSLChangeHdskState(ctx, HandshakeHelloDone);
- break;
- case SSL_DHE_DSS:
- case SSL_DHE_DSS_EXPORT:
- case SSL_DHE_RSA:
- case SSL_DHE_RSA_EXPORT:
- case SSL_Fortezza:
- SSLChangeHdskState(ctx, HandshakeKeyExchange);
- break;
- default:
- ASSERTMSG("Unknown or unexpected key exchange method");
- break;
- }
- else if (ctx->state == HandshakeClientCertificate)
- { SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
- if (ctx->peerCert != 0)
- ctx->certReceived = 1;
- }
- break;
- case SSL_certificate_request: /* state stays in HandshakeHelloDone; distinction is in ctx->certRequested */
- if (ctx->peerCert == 0)
- { ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
- return ERR(SSLProtocolErr);
- }
- ctx->certRequested = 1;
- break;
- case SSL_server_key_exchange:
- SSLChangeHdskState(ctx, HandshakeHelloDone);
- break;
- case SSL_server_hello_done:
- if (ctx->certRequested)
- { if (ctx->localCert != 0 && ctx->x509Requested)
- { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
- return err;
- }
- else
- { if (ERR(err = SSLSendAlert(alert_warning, alert_no_certificate, ctx)) != 0)
- return err;
- }
- }
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
- return err;
- assert(ctx->sslTslCalls != NULL);
- if (ERR(err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
- ERR(err = SSLInitPendingCiphers(ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
- if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
- return err;
- if (ctx->certSent)
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify, ctx)) != 0)
- return err;
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
- return err;
- /* Install new cipher spec on write side */
- if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- ctx->writeCipher = ctx->writePending;
- /* Can't send data until Finished is sent */
- ctx->writeCipher.ready = 0;
-
- /* Zero out old data */
- memset(&ctx->writePending, 0, sizeof(CipherContext));
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
- return err;
- /* Finished has been sent; enable data dransfer on write channel */
- ctx->writeCipher.ready = 1;
- SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
- break;
- case SSL_certificate_verify:
- SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
- break;
- case SSL_client_key_exchange:
- assert(ctx->sslTslCalls != NULL);
- if (ERR(err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
- ERR(err = SSLInitPendingCiphers(ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
- memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
- if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
- return err;
- if (ctx->certReceived) {
- SSLChangeHdskState(ctx, HandshakeClientCertVerify);
- }
- else {
- SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
- }
- break;
- case SSL_finished:
- /* Handshake is over; enable data transfer on read channel */
- ctx->readCipher.ready = 1;
- /* If writePending is set, we haven't yet sent a finished message; send it */
- if (ctx->writePending.ready != 0)
- { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
- return err;
-
- /* Install new cipher spec on write side */
- if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return err;
- }
- ctx->writeCipher = ctx->writePending;
- ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
- memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
- if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
- return err;
- ctx->writeCipher.ready = 1;
- }
- if (ctx->protocolSide == SSL_ServerSide) {
- SSLChangeHdskState(ctx, HandshakeServerReady);
- }
- else {
- SSLChangeHdskState(ctx, HandshakeClientReady);
- }
- if (ctx->peerID.data != 0)
- ERR(SSLAddSessionData(ctx));
- break;
- default:
- ASSERTMSG("Unknown State");
- break;
- }
-
- return SSLNoErr;
-}
-
-SSLErr
-SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
-{ SSLErr err;
- SSLRecord rec;
-
- if (ERR(err = msgFunc(&rec, ctx)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- goto fail;
- }
-
- if (rec.contentType == SSL_handshake)
- { if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
- ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- goto fail;
- }
- SSLLogHdskMsg((SSLHandshakeType)rec.contents.data[0], 1);
- }
-
- assert(ctx->sslTslCalls != NULL);
- if (ERR(err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
- goto fail;
-
- err = SSLNoErr;
-fail:
- SSLFreeBuffer(&rec.contents, &ctx->sysCtx);
-
- return err;
-}
-
-SSLErr
-SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
-{ SSLErr err;
-
- if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
- return err;
-
- if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
- ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
- { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
- return err;
- }
-
- if (ERR(err = SSLAdvanceHandshake(SSL_client_hello, ctx)) != 0)
- return err;
-
- return SSLNoErr;
-}
-
-/* log changes in handshake state */
-#if LOG_HDSK_STATE
-
-#include <stdio.h>
-
-char *hdskStateToStr(SSLHandshakeState state)
-{
- static char badStr[100];
-
- switch(state) {
- case SSLUninitialized:
- return "SSLUninitialized";
- case HandshakeServerUninit:
- return "HandshakeServerUninit";
- case HandshakeClientUninit:
- return "HandshakeClientUninit";
- case SSLGracefulClose:
- return "SSLGracefulClose";
- case SSLErrorClose:
- return "SSLErrorClose";
- case SSLNoNotifyClose:
- return "SSLNoNotifyClose";
- case HandshakeServerHello:
- return "HandshakeServerHello";
- case HandshakeServerHelloUnknownVersion:
- return "HandshakeServerHelloUnknownVersion";
- case HandshakeKeyExchange:
- return "HandshakeKeyExchange";
- case HandshakeCertificate:
- return "HandshakeCertificate";
- case HandshakeHelloDone:
- return "HandshakeHelloDone";
- case HandshakeClientCertificate:
- return "HandshakeClientCertificate";
- case HandshakeClientKeyExchange:
- return "HandshakeClientKeyExchange";
- case HandshakeClientCertVerify:
- return "HandshakeClientCertVerify";
- case HandshakeChangeCipherSpec:
- return "HandshakeChangeCipherSpec";
- case HandshakeFinished:
- return "HandshakeFinished";
- case HandshakeSSL2ClientMasterKey:
- return "HandshakeSSL2ClientMasterKey";
- case HandshakeSSL2ClientFinished:
- return "HandshakeSSL2ClientFinished";
- case HandshakeSSL2ServerHello:
- return "HandshakeSSL2ServerHello";
- case HandshakeSSL2ServerVerify:
- return "HandshakeSSL2ServerVerify";
- case HandshakeSSL2ServerFinished:
- return "HandshakeSSL2ServerFinished";
- case HandshakeServerReady:
- return "HandshakeServerReady";
- case HandshakeClientReady:
- return "HandshakeClientReady";
- default:
- sprintf(badStr, "Unknown state (%d(d)", state);
- return badStr;
- }
-}
-
-void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
-{
- printf("...hdskState = %s\n", hdskStateToStr(newState));
- ctx->state = newState;
-}
-
-#endif /* LOG_HDSK_STATE */
-
-/* log handshake messages */
-
-#if LOG_HDSK_MSG
-
-#include <stdio.h>
-
-static char *hdskMsgToStr(SSLHandshakeType msg)
-{
- static char badStr[100];
-
- switch(msg) {
- case SSL_hello_request:
- return "SSL_hello_request";
- case SSL_client_hello:
- return "SSL_client_hello";
- case SSL_server_hello:
- return "SSL_server_hello";
- case SSL_certificate:
- return "SSL_certificate";
- case SSL_server_key_exchange:
- return "SSL_server_key_exchange";
- case SSL_certificate_request:
- return "SSL_certificate_request";
- case SSL_server_hello_done:
- return "SSL_server_hello_done";
- case SSL_certificate_verify:
- return "SSL_certificate_verify";
- case SSL_client_key_exchange:
- return "SSL_client_key_exchange";
- case SSL_finished:
- return "SSL_finished";
- case SSL_MAGIC_no_certificate_alert:
- return "SSL_MAGIC_no_certificate_alert";
- default:
- sprintf(badStr, "Unknown state (%d(d)", msg);
- return badStr;
- }
-}
-
-void SSLLogHdskMsg(SSLHandshakeType msg, char sent)
-{
- printf("---%s handshake msg %s\n",
- hdskMsgToStr(msg), (sent ? "sent" : "recv"));
-}
-
-#endif /* LOG_HDSK_MSG */
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslrec.c
-
- Contains: Encryption, decryption and MACing of data
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: sslrec.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslrec.c Encryption, decryption and MACing of data
-
- All the transformations which occur between plaintext and the
- secured, authenticated data that goes out over the wire. Also,
- detects incoming SSL 2 hello messages and hands them off to the SSL 2
- record layer (and hands all SSL 2 reading & writing off to the SSL 2
- layer).
-
- ****************************************************************** */
-
-
-#include "ssl.h"
-
-#ifndef _SSLREC_H_
-#include "sslrec.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _CRYPTTYPE_H_
-#include "cryptType.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _SSL2_H_
-#include "ssl2.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#include "appleGlue.h"
-#include <string.h>
-#include <assert.h>
-
-/*
- * Lots of servers fail to provide closure alerts when they disconnect.
- * For now we'll just accept it as long as it occurs on a clean record boundary
- * (and the handshake is complete).
- */
-#define SSL_ALLOW_UNNOTICED_DISCONNECT 1
-
-/* ReadSSLRecord
- * Attempt to read & decrypt an SSL record.
- */
-SSLErr
-SSLReadRecord(SSLRecord *rec, SSLContext *ctx)
-{ SSLErr err;
- UInt32 len, contentLen;
- UInt8 *progress;
- SSLBuffer readData, cipherFragment;
-
- if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < 5)
- { if (ctx->partialReadBuffer.data)
- if ((err = SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return ERR(err);
- }
- if ((err = SSLAllocBuffer(&ctx->partialReadBuffer, DEFAULT_BUFFER_SIZE, &ctx->sysCtx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return ERR(err);
- }
- }
-
- if (ctx->negProtocolVersion == SSL_Version_Undetermined ||
- ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
- if (ctx->amountRead < 1)
- { readData.length = 1 - ctx->amountRead;
- readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
- len = readData.length;
- err = sslIoRead(readData, &len, ctx);
- if(err != 0)
- { if (err == SSLWouldBlockErr)
- ctx->amountRead += len;
- else
- SSLFatalSessionAlert(alert_close_notify, ctx);
- return err;
- }
- ctx->amountRead += len;
- }
-
-/* In undetermined cases, if the first byte isn't in the range of SSL 3.0
- * record types, this is an SSL 2.0 record
- */
- switch (ctx->negProtocolVersion)
- { case SSL_Version_Undetermined:
- case SSL_Version_3_0_With_2_0_Hello:
- if (ctx->partialReadBuffer.data[0] < SSL_smallest_3_0_type ||
- ctx->partialReadBuffer.data[0] > SSL_largest_3_0_type)
- return SSL2ReadRecord(rec, ctx);
- else
- break;
- case SSL_Version_2_0:
- return SSL2ReadRecord(rec, ctx);
- default:
- break;
- }
-
- if (ctx->amountRead < 5)
- { readData.length = 5 - ctx->amountRead;
- readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
- len = readData.length;
- err = sslIoRead(readData, &len, ctx);
- if(err != 0)
- {
- switch(err) {
- case SSLWouldBlockErr:
- ctx->amountRead += len;
- break;
- #if SSL_ALLOW_UNNOTICED_DISCONNECT
- case SSLConnectionClosedGraceful:
- /* legal if we're on record boundary and we've gotten past
- * the handshake */
- if((ctx->amountRead == 0) && /* nothing pending */
- (len == 0) && /* nothing new */
- (ctx->state == HandshakeClientReady)) { /* handshake done */
- /*
- * This means that the server has disconnected without
- * sending a closure alert notice. This is technically
- * illegal per the SSL3 spec, but about half of the
- * servers out there do it, so we report it as a separate
- * error which most clients - including (currently)
- * URLAccess - ignore by treating it the same as
- * a SSLConnectionClosedGraceful error. Paranoid
- * clients can detect it and handle it however they
- * want to.
- */
- SSLChangeHdskState(ctx, SSLNoNotifyClose);
- err = SSLConnectionClosedNoNotify;
- break;
- }
- else {
- /* illegal disconnect */
- err = SSLConnectionClosedError;
- /* and drop thru to default: fatal alert */
- }
- #endif /* SSL_ALLOW_UNNOTICED_DISCONNECT */
- default:
- SSLFatalSessionAlert(alert_close_notify, ctx);
- break;
- }
- return err;
- }
- ctx->amountRead += len;
- }
-
- CASSERT(ctx->amountRead >= 5);
-
- progress = ctx->partialReadBuffer.data;
- rec->contentType = *progress++;
- if (rec->contentType < SSL_smallest_3_0_type ||
- rec->contentType > SSL_largest_3_0_type)
- return ERR(SSLProtocolErr);
-
- rec->protocolVersion = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
- progress += 2;
- contentLen = SSLDecodeInt(progress, 2);
- progress += 2;
- if (contentLen > (16384 + 2048)) /* Maximum legal length of an SSLCipherText payload */
- { SSLFatalSessionAlert(alert_unexpected_message, ctx);
- return ERR(SSLProtocolErr);
- }
-
- if (ctx->partialReadBuffer.length < 5 + contentLen)
- { if ((err = SSLReallocBuffer(&ctx->partialReadBuffer, 5 + contentLen, &ctx->sysCtx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return ERR(err);
- }
- }
-
- if (ctx->amountRead < 5 + contentLen)
- { readData.length = 5 + contentLen - ctx->amountRead;
- readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
- len = readData.length;
- err = sslIoRead(readData, &len, ctx);
- if(err != 0)
- { if (err == SSLWouldBlockErr)
- ctx->amountRead += len;
- else
- SSLFatalSessionAlert(alert_close_notify, ctx);
- return err;
- }
- ctx->amountRead += len;
- }
-
- CASSERT(ctx->amountRead >= 5 + contentLen);
-
- cipherFragment.data = ctx->partialReadBuffer.data + 5;
- cipherFragment.length = contentLen;
-
-/* Decrypt the payload & check the MAC, modifying the length of the buffer to indicate the
- * amount of plaintext data after adjusting for the block size and removing the MAC
- * (this function generates its own alerts)
- */
- assert(ctx->sslTslCalls != NULL);
- if ((err = ctx->sslTslCalls->decryptRecord(rec->contentType,
- &cipherFragment, ctx)) != 0)
- return err;
-
-/* We appear to have sucessfully received a record; increment the sequence number */
- IncrementUInt64(&ctx->readCipher.sequenceNum);
-
-/* Allocate a buffer to return the plaintext in and return it */
- if ((err = SSLAllocBuffer(&rec->contents, cipherFragment.length, &ctx->sysCtx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return ERR(err);
- }
- memcpy(rec->contents.data, cipherFragment.data, cipherFragment.length);
-
- ctx->amountRead = 0; /* We've used all the data in the cache */
-
- return SSLNoErr;
-}
-
-/* common for sslv3 and tlsv1, except for the computeMac callout */
-SSLErr SSLVerifyMac(
- UInt8 type,
- SSLBuffer data,
- UInt8 *compareMAC,
- SSLContext *ctx)
-{
- SSLErr err;
- UInt8 macData[MAX_DIGEST_SIZE];
- SSLBuffer secret, mac;
-
- secret.data = ctx->readCipher.macSecret;
- secret.length = ctx->readCipher.macRef->hash->digestSize;
- mac.data = macData;
- mac.length = ctx->readCipher.macRef->hash->digestSize;
-
- assert(ctx->sslTslCalls != NULL);
- if ((err = ctx->sslTslCalls->computeMac(type,
- data,
- mac,
- &ctx->readCipher,
- ctx->readCipher.sequenceNum,
- ctx)) != 0)
- return ERR(err);
-
- if ((memcmp(mac.data, compareMAC, mac.length)) != 0) {
- errorLog0("ssl3VerifyMac: Mac verify failure\n");
- return ERR(SSLProtocolErr);
- }
- return SSLNoErr;
-}
-
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/* *********************************************************************
- File: sslsess.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslsess.c SSL Session DB interface
-
- This file contains functions which interact with the session database
- to store and restore sessions and retrieve information from packed
- session records.
-
- ****************************************************************** */
-
-#ifndef _SSL_H_
-#include "ssl.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLSESS_H_
-#include "sslsess.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _CIPHER_SPECS_H_
-#include "cipherSpecs.h"
-#endif
-
-#include "appleSession.h"
-#include <assert.h>
-#include <string.h>
-#include <stddef.h>
-
-typedef struct
-{ int sessionIDLen;
- UInt8 sessionID[32];
- SSLProtocolVersion protocolVersion;
- UInt16 cipherSuite;
- UInt16 padding; /* so remainder is word aligned */
- UInt8 masterSecret[48];
- int certCount;
- UInt8 certs[1]; /* Actually, variable length */
-} ResumableSession;
-
-/*
- * Cook up a (private) resumable session blob, based on the
- * specified ctx, store it with ctx->peerID as the key.
- * NOTE: This is contrary to the SSLRef3 spec, which claims that
- * servers store resumable sessions using ctx->sessionID as the key.
- * I don' think this is an issue...is it?
- */
-SSLErr
-SSLAddSessionData(const SSLContext *ctx)
-{ SSLErr err;
- uint32 sessionIDLen;
- SSLBuffer sessionID;
- ResumableSession *session;
- int certCount;
- SSLCertificate *cert;
- uint8 *certDest;
-
- /* If we don't know who the peer is, we can't store a session */
- if (ctx->peerID.data == 0)
- return SSLSessionNotFoundErr;
-
- sessionIDLen = offsetof(ResumableSession, certs);
- cert = ctx->peerCert;
- certCount = 0;
- while (cert)
- { ++certCount;
- sessionIDLen += 4 + cert->derCert.length;
- cert = cert->next;
- }
-
- if ((err = SSLAllocBuffer(&sessionID, sessionIDLen, &ctx->sysCtx)) != 0)
- return err;
-
- session = (ResumableSession*)sessionID.data;
-
- session->sessionIDLen = ctx->sessionID.length;
- memcpy(session->sessionID, ctx->sessionID.data, session->sessionIDLen);
- session->protocolVersion = ctx->negProtocolVersion;
- session->cipherSuite = ctx->selectedCipher;
- memcpy(session->masterSecret, ctx->masterSecret, 48);
- session->certCount = certCount;
- session->padding = 0;
-
- certDest = session->certs;
- cert = ctx->peerCert;
- while (cert)
- { certDest = SSLEncodeInt(certDest, cert->derCert.length, 4);
- memcpy(certDest, cert->derCert.data, cert->derCert.length);
- certDest += cert->derCert.length;
- cert = cert->next;
- }
-
- err = sslAddSession(ctx->peerID, sessionID);
- SSLFreeBuffer(&sessionID, &ctx->sysCtx);
-
- return err;
-}
-
-/*
- * Retrieve resumable session data, from key ctx->peerID.
- */
-SSLErr
-SSLGetSessionData(SSLBuffer *sessionData, const SSLContext *ctx)
-{ SSLErr err;
-
- if (ctx->peerID.data == 0)
- return ERR(SSLSessionNotFoundErr);
-
- sessionData->data = 0;
-
- err = sslGetSession(ctx->peerID, sessionData);
- if (sessionData->data == 0)
- return ERR(SSLSessionNotFoundErr);
-
- return err;
-}
-
-SSLErr
-SSLDeleteSessionData(const SSLContext *ctx)
-{ SSLErr err;
-
- if (ctx->peerID.data == 0)
- return SSLSessionNotFoundErr;
-
- err = sslDeleteSession(ctx->peerID);
- return err;
-}
-
-/*
- * Given a sessionData blob, obtain the associated sessionID (NOT the key...).
- */
-SSLErr
-SSLRetrieveSessionID(
- const SSLBuffer sessionData,
- SSLBuffer *identifier,
- const SSLContext *ctx)
-{ SSLErr err;
- ResumableSession *session;
-
- session = (ResumableSession*) sessionData.data;
- if ((err = SSLAllocBuffer(identifier, session->sessionIDLen, &ctx->sysCtx)) != 0)
- return err;
- memcpy(identifier->data, session->sessionID, session->sessionIDLen);
- return SSLNoErr;
-}
-
-/*
- * Obtain the protocol version associated with a specified resumable session blob.
- */
-SSLErr
-SSLRetrieveSessionProtocolVersion(
- const SSLBuffer sessionData,
- SSLProtocolVersion *version,
- const SSLContext *ctx)
-{ ResumableSession *session;
-
- session = (ResumableSession*) sessionData.data;
- *version = session->protocolVersion;
- return SSLNoErr;
-}
-
-/*
- * Retrieve session state from specified sessionData blob, install into
- * ctx. Presumably, ctx->sessionID and
- * ctx->negProtocolVersion are already init'd (from the above two functions).
- */
-
-/*
- * Netscape Enterprise Server is known to change cipherspecs upon session resumption.
- * For example, connecting to cdnow.com with all ciphersuites enabled results in
- * CipherSuite 4 (SSL_RSA_WITH_RC4_128_MD5) being selected on the first session,
- * and CipherSuite 10 (SSL_RSA_WITH_3DES_EDE_CBC_SHA) being selected on subsequent
- * sessions. This is contrary to the SSL3.0 spec, sesion 7.6.1.3, describing the
- * Server Hello message.
- *
- * This anomaly does not occur if only RC4 ciphers are enabled in the Client Hello
- * message. It also does not happen in SSL V2.
- */
-#define ALLOW_CIPHERSPEC_CHANGE 1
-
-SSLErr
-SSLInstallSessionFromData(const SSLBuffer sessionData, SSLContext *ctx)
-{ SSLErr err;
- ResumableSession *session;
- uint8 *storedCertProgress;
- SSLCertificate *cert, *lastCert;
- int certCount;
- uint32 certLen;
-
- session = (ResumableSession*)sessionData.data;
-
- CASSERT(ctx->negProtocolVersion == session->protocolVersion);
-
- /*
- * For SSLv3 and TLSv1, we know that selectedCipher has already been specified in
- * SSLProcessServerHello(). An SSLv2 server hello message with a session
- * ID hit contains no CipherKind field so we set it here.
- */
- if(ctx->negProtocolVersion == SSL_Version_2_0) {
- if(ctx->protocolSide == SSL_ClientSide) {
- assert(ctx->selectedCipher == 0);
- ctx->selectedCipher = session->cipherSuite;
- }
- else {
- /*
- * Else...what if they don't match? Could never happen, right?
- * Wouldn't that mean the client is trying to switch ciphers on us?
- */
- if(ctx->selectedCipher != session->cipherSuite) {
- errorLog2("+++SSL2: CipherSpec change from %d to %d on session "
- "resume\n",
- session->cipherSuite, ctx->selectedCipher);
- return SSLProtocolErr;
- }
- }
- }
- else {
- assert(ctx->selectedCipher != 0);
- if(ctx->selectedCipher != session->cipherSuite) {
- #if ALLOW_CIPHERSPEC_CHANGE
- dprintf2("+++WARNING: CipherSpec change from %d to %d on session resume\n",
- session->cipherSuite, ctx->selectedCipher);
- #else
- errorLog2("+++SSL: CipherSpec change from %d to %d on session resume\n",
- session->cipherSuite, ctx->selectedCipher);
- return SSLProtocolErr;
- #endif
- }
- }
- if ((err = FindCipherSpec(ctx)) != 0) {
- return err;
- }
- memcpy(ctx->masterSecret, session->masterSecret, 48);
-
- lastCert = 0;
- storedCertProgress = session->certs;
- certCount = session->certCount;
-
- while (certCount--)
- {
- cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
- if(cert == NULL) {
- return SSLMemoryErr;
- }
- cert->next = 0;
- certLen = SSLDecodeInt(storedCertProgress, 4);
- storedCertProgress += 4;
- if ((err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
- {
- sslFree(cert);
- return err;
- }
- memcpy(cert->derCert.data, storedCertProgress, certLen);
- storedCertProgress += certLen;
- if (lastCert == 0)
- ctx->peerCert = cert;
- else
- lastCert->next = cert;
- lastCert = cert;
- }
-
- return SSLNoErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: ssltrspt.c
-
- Contains: SSLContext transport layer
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: ssltrspt.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ssltrspt.c Data transportation functionality
-
- Transports data between the application and the record layer; also
- hands off handshake, alert, and change cipher spec messages to their
- handlers. Also, ensures that negotiation happens before application
- data goes out on the wire.
-
- ****************************************************************** */
-
-#ifndef _SSLTRSPT_H_
-#include "ssltrspt.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLCTX_H_
-#include "sslrec.h"
-#endif
-
-#ifndef _SSLALERT_H_
-#include "sslalert.h"
-#endif
-
-#ifndef _SSLSESS_H_
-#include "sslsess.h"
-#endif
-
-#ifndef _SSL2_H_
-#include "ssl2.h"
-#endif
-
-#ifndef _APPLE_GLUE_H_
-#include "appleGlue.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#ifndef _CIPHER_SPECS_H_
-#include "cipherSpecs.h"
-#endif
-
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
-#include <assert.h>
-#include <string.h>
-
-#define SSL_IO_TRACE 0
-#if SSL_IO_TRACE
-static void sslIoTrace(
- const char *op,
- UInt32 req,
- UInt32 moved,
- OSStatus stat)
-{
- printf("===%s: req %4d moved %4d status %d\n",
- op, req, moved, stat);
-}
-
-#else
-#define sslIoTrace(op, req, moved, stat)
-#endif /* SSL_IO_TRACE */
-
-static SSLErr SSLProcessProtocolMessage(SSLRecord rec, SSLContext *ctx);
-static SSLErr SSLHandshakeProceed(SSLContext *ctx);
-static SSLErr SSLInitConnection(SSLContext *ctx);
-static SSLErr SSLServiceWriteQueue(SSLContext *ctx);
-
-OSStatus
-SSLWrite(
- SSLContext *ctx,
- const void * data,
- UInt32 dataLength,
- UInt32 *bytesWritten) /* RETURNED */
-{
- SSLErr err;
- SSLRecord rec;
- UInt32 dataLen, processed;
-
- if((ctx == NULL) || (bytesWritten == NULL)) {
- return paramErr;
- }
- dataLen = dataLength;
- processed = 0; /* Initialize in case we return with SSLWouldBlockErr */
- *bytesWritten = 0;
-
- switch(ctx->state) {
- case SSLGracefulClose:
- err = SSLConnectionClosedGraceful;
- goto abort;
- case SSLErrorClose:
- err = SSLConnectionClosedError;
- goto abort;
- default:
- /* FIXME - original code didn't check for handshake in progress -
- * should we?
- */
- sslIoTrace("SSLWrite", dataLength, 0, badReqErr);
- return badReqErr;
- case HandshakeServerReady:
- case HandshakeClientReady:
- break;
- }
-
- /* First, we have to wait until the session is ready to send data,
- so the encryption keys and such have been established. */
- err = SSLNoErr;
- while (ctx->writeCipher.ready == 0)
- { if ((err = SSLHandshakeProceed(ctx)) != 0)
- goto exit;
- }
-
- /* Attempt to empty the write queue before queueing more data */
- if ((err = SSLServiceWriteQueue(ctx)) != 0)
- goto abort;
-
- processed = 0;
- /* Fragment, package and encrypt the data and queue the resulting data for sending */
- while (dataLen > 0)
- { rec.contentType = SSL_application_data;
- rec.protocolVersion = ctx->negProtocolVersion;
- rec.contents.data = ((UInt8*)data) + processed;
-
- if (dataLen < MAX_RECORD_LENGTH)
- rec.contents.length = dataLen;
- else
- rec.contents.length = MAX_RECORD_LENGTH;
-
- assert(ctx->sslTslCalls != NULL);
- if (ERR(err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
- goto exit;
-
- processed += rec.contents.length;
- dataLen -= rec.contents.length;
- }
-
- /* All the data has been advanced to the write queue */
- *bytesWritten = processed;
- if (ERR(err = SSLServiceWriteQueue(ctx)) != 0)
- goto exit;
-
- err = SSLNoErr;
-exit:
- if (err != 0 && err != SSLWouldBlockErr && err != SSLConnectionClosedGraceful) {
- dprintf1("SSLWrite: going to state errorCLose due to err %d\n",
- err);
- SSLChangeHdskState(ctx, SSLErrorClose);
- }
-abort:
- sslIoTrace("SSLWrite", dataLength, *bytesWritten, sslErrToOsStatus(err));
- return sslErrToOsStatus(err);
-}
-
-OSStatus
-SSLRead (
- SSLContext *ctx,
- void * data,
- UInt32 dataLength,
- UInt32 *processed) /* RETURNED */
-{
- SSLErr err;
- UInt8 *progress;
- UInt32 bufSize, remaining, count;
- SSLRecord rec;
-
- if((ctx == NULL) || (processed == NULL)) {
- return paramErr;
- }
- bufSize = dataLength;
- *processed = 0; /* Initialize in case we return with SSLWouldBlockErr */
-
- /* first handle cases in which we know we're finished */
- switch(ctx->state) {
- case SSLGracefulClose:
- err = SSLConnectionClosedGraceful;
- goto abort;
- case SSLErrorClose:
- err = SSLConnectionClosedError;
- goto abort;
- case SSLNoNotifyClose:
- err = SSLConnectionClosedNoNotify;
- goto abort;
- default:
- break;
- }
-
- /* First, we have to wait until the session is ready to receive data,
- so the encryption keys and such have been established. */
- err = SSLNoErr;
- while (ctx->readCipher.ready == 0)
- { if (ERR(err = SSLHandshakeProceed(ctx)) != 0)
- goto exit;
- }
-
- /* Attempt to service the write queue */
- if (ERR(err = SSLServiceWriteQueue(ctx)) != 0)
- { if (err != SSLWouldBlockErr)
- goto exit;
- err = SSLNoErr; /* Write blocking shouldn't stop attempts to read */
- }
-
- remaining = bufSize;
- progress = (UInt8*)data;
- if (ctx->receivedDataBuffer.data)
- { count = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
- if (count > bufSize)
- count = bufSize;
- memcpy(data, ctx->receivedDataBuffer.data + ctx->receivedDataPos, count);
- remaining -= count;
- progress += count;
- *processed += count;
- ctx->receivedDataPos += count;
- }
-
- CASSERT(ctx->receivedDataPos <= ctx->receivedDataBuffer.length);
- CASSERT(*processed + remaining == bufSize);
- CASSERT(progress == ((UInt8*)data) + *processed);
-
- if (ctx->receivedDataBuffer.data != 0 &&
- ctx->receivedDataPos >= ctx->receivedDataBuffer.length)
- { SSLFreeBuffer(&ctx->receivedDataBuffer, &ctx->sysCtx);
- ctx->receivedDataBuffer.data = 0;
- ctx->receivedDataPos = 0;
- }
-
- /*
- * This while statement causes a hang when using nonblocking low-level I/O!
- while (remaining > 0 && ctx->state != SSLGracefulClose)
- ..what we really have to do is just return as soon as we read one
- record. A performance hit in the nonblocking case, but that is
- the only way this code can work in both modes...
- */
- if (remaining > 0 && ctx->state != SSLGracefulClose)
- { CASSERT(ctx->receivedDataBuffer.data == 0);
- if (ERR(err = SSLReadRecord(&rec, ctx)) != 0)
- goto exit;
-
- if (rec.contentType == SSL_application_data ||
- rec.contentType == SSL_version_2_0_record)
- { if (rec.contents.length <= remaining)
- { memcpy(progress, rec.contents.data, rec.contents.length);
- remaining -= rec.contents.length;
- progress += rec.contents.length;
- *processed += rec.contents.length;
- /* COMPILER BUG!
- * This:
- * if (ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
- * passes the address of rec to SSLFreeBuffer, not the address
- * of the contents field (which should be offset 8 from the start
- * of rec).
- */
- {
- SSLBuffer *b = &rec.contents;
- if (ERR(err = SSLFreeBuffer(b, &ctx->sysCtx)) != 0) {
- goto exit;
- }
- }
- }
- else
- { memcpy(progress, rec.contents.data, remaining);
- progress += remaining;
- *processed += remaining;
- ctx->receivedDataBuffer = rec.contents;
- ctx->receivedDataPos = remaining;
- remaining = 0;
- }
- }
- else
- { if (ERR(err = SSLProcessProtocolMessage(rec, ctx)) != 0)
- goto exit;
- if (ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
- goto exit;
- }
- }
-
- err = SSLNoErr;
-
-exit:
- /* shut down on serious errors */
- switch(err) {
- case SSLNoErr:
- case SSLWouldBlockErr:
- case SSLConnectionClosedGraceful:
- case SSLConnectionClosedNoNotify:
- break;
- default:
- dprintf1("SSLRead: going to state errorClose due to err %d\n",
- err);
- SSLChangeHdskState(ctx, SSLErrorClose);
- break;
- }
-abort:
- sslIoTrace("SSLRead ", dataLength, *processed, sslErrToOsStatus(err));
- return sslErrToOsStatus(err);
-}
-
-#if SSL_DEBUG
-#include "appleCdsa.h"
-#endif
-
-OSStatus
-SSLHandshake(SSLContext *ctx)
-{
- SSLErr err;
-
- if(ctx == NULL) {
- return paramErr;
- }
- if (ctx->state == SSLGracefulClose)
- return sslErrToOsStatus(SSLConnectionClosedGraceful);
- if (ctx->state == SSLErrorClose)
- return sslErrToOsStatus(SSLConnectionClosedError);
-
- if(ctx->protocolSide == SSL_ServerSide) {
- /* some things the caller really has to have done by now... */
- if((ctx->localCert == NULL) ||
- (ctx->signingPrivKey == NULL) ||
- (ctx->signingPubKey == NULL) ||
- (ctx->signingKeyCsp == 0)) {
- errorLog0("SSLHandshake: insufficient init\n");
- return badReqErr;
- }
- }
- if(ctx->validCipherSpecs == NULL) {
- /* build list of legal cipherSpecs */
- err = sslBuildCipherSpecArray(ctx);
- if(err) {
- return err;
- }
- }
- err = SSLNoErr;
- while (ctx->readCipher.ready == 0 || ctx->writeCipher.ready == 0)
- { if (ERR(err = SSLHandshakeProceed(ctx)) != 0)
- return sslErrToOsStatus(err);
- }
-
- /* one more flush at completion of successful handshake */
- if ((err = SSLServiceWriteQueue(ctx)) != 0) {
- return sslErrToOsStatus(err);
- }
- return noErr;
-}
-
-
-static SSLErr
-SSLHandshakeProceed(SSLContext *ctx)
-{ SSLErr err;
- SSLRecord rec;
-
- if (ctx->state == SSLUninitialized)
- if (ERR(err = SSLInitConnection(ctx)) != 0)
- return err;
- if (ERR(err = SSLServiceWriteQueue(ctx)) != 0)
- return err;
- CASSERT(ctx->readCipher.ready == 0);
- if (ERR(err = SSLReadRecord(&rec, ctx)) != 0)
- return err;
- if (ERR(err = SSLProcessProtocolMessage(rec, ctx)) != 0)
- { SSLFreeBuffer(&rec.contents, &ctx->sysCtx);
- return err;
- }
- if (ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
- return err;
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLInitConnection(SSLContext *ctx)
-{ SSLErr err;
-
- if (ctx->protocolSide == SSL_ClientSide) {
- SSLChangeHdskState(ctx, HandshakeClientUninit);
- }
- else
- { CASSERT(ctx->protocolSide == SSL_ServerSide);
- SSLChangeHdskState(ctx, HandshakeServerUninit);
- }
-
- if (ctx->peerID.data != 0)
- { ERR(SSLGetSessionData(&ctx->resumableSession, ctx));
- /* Ignore errors; just treat as uncached session */
- }
-
- /*
- * If we have a cached resumable session, blow it off if it's a higher
- * version than the max currently allowed. Note that this means that once
- * a process negotiates a given version with a given server/port, it won't
- * be able to negotiate a higher version. We might want to revisit this.
- */
- if (ctx->resumableSession.data != 0) {
-
- SSLProtocolVersion savedVersion;
-
- if (ERR(err = SSLRetrieveSessionProtocolVersion(ctx->resumableSession,
- &savedVersion, ctx)) != 0) {
- return err;
- }
- if(savedVersion > ctx->maxProtocolVersion) {
- SSLLogResumSess("===Resumable session protocol mismatch\n");
- SSLFreeBuffer(&ctx->resumableSession, &ctx->sysCtx);
- }
- else {
- SSLLogResumSess("===attempting to resume session\n");
- /*
- * A bit of a special case for server side here. If currently
- * configged to allow for SSL3/TLS1 with an SSL2 hello, we
- * don't want to preclude the possiblity of an SSL2 hello...
- * so we'll just leave the negProtocolVersion alone in the server case.
- */
- if(ctx->protocolSide == SSL_ClientSide) {
- ctx->negProtocolVersion = savedVersion;
- }
- }
- }
-
-/* If we're the client & handshake hasn't yet begun, start it by
- * pretending we just received a hello request
- */
- if (ctx->state == HandshakeClientUninit && ctx->writeCipher.ready == 0)
- { switch (ctx->negProtocolVersion)
- { case SSL_Version_Undetermined:
- case SSL_Version_3_0_With_2_0_Hello:
- case SSL_Version_2_0:
- if (ERR(err = SSL2AdvanceHandshake(ssl2_mt_kickstart_handshake, ctx)) != 0)
- return err;
- break;
- case SSL_Version_3_0_Only:
- case SSL_Version_3_0:
- case TLS_Version_1_0_Only:
- case TLS_Version_1_0:
- if (ERR(err = SSLAdvanceHandshake(SSL_hello_request, ctx)) != 0)
- return err;
- break;
- default:
- sslPanic("Bad protocol version");
- break;
- }
- }
-
- return SSLNoErr;
-}
-
-static SSLErr
-SSLServiceWriteQueue(SSLContext *ctx)
-{ SSLErr err = SSLNoErr, werr = SSLNoErr;
- UInt32 written = 0;
- SSLBuffer buf, recBuf;
- WaitingRecord *rec;
-
- while (!werr && ((rec = ctx->recordWriteQueue) != 0))
- { buf.data = rec->data.data + rec->sent;
- buf.length = rec->data.length - rec->sent;
- werr = sslIoWrite(buf, &written, ctx);
- rec->sent += written;
- if (rec->sent >= rec->data.length)
- { CASSERT(rec->sent == rec->data.length);
- CASSERT(err == 0);
- err = SSLFreeBuffer(&rec->data, &ctx->sysCtx);
- CASSERT(err == 0);
- recBuf.data = (UInt8*)rec;
- recBuf.length = sizeof(WaitingRecord);
- ctx->recordWriteQueue = rec->next;
- err = SSLFreeBuffer(&recBuf, &ctx->sysCtx);
- CASSERT(err == 0);
- }
- if (ERR(err))
- return err;
- CASSERT(ctx->recordWriteQueue == 0 || ctx->recordWriteQueue->sent == 0);
- }
-
- return werr;
-}
-
-#if LOG_RX_PROTOCOL
-static void sslLogRxProto(const char *msgType)
-{
- printf("---received protoMsg %s\n", msgType);
-}
-#else
-#define sslLogRxProto(msgType)
-#endif /* LOG_RX_PROTOCOL */
-
-static SSLErr
-SSLProcessProtocolMessage(SSLRecord rec, SSLContext *ctx)
-{ SSLErr err;
-
- switch (rec.contentType)
- { case SSL_handshake:
- sslLogRxProto("SSL_handshake");
- ERR(err = SSLProcessHandshakeRecord(rec, ctx));
- break;
- case SSL_alert:
- sslLogRxProto("SSL_alert");
- ERR(err = SSLProcessAlert(rec, ctx));
- break;
- case SSL_change_cipher_spec:
- sslLogRxProto("SSL_change_cipher_spec");
- ERR(err = SSLProcessChangeCipherSpec(rec, ctx));
- break;
- case SSL_version_2_0_record:
- sslLogRxProto("SSL_version_2_0_record");
- ERR(err = SSL2ProcessMessage(rec, ctx));
- break;
- default:
- sslLogRxProto("Bad msg");
- return ERR(SSLProtocolErr);
- }
-
- return err;
-}
-
-OSStatus
-SSLClose(SSLContext *ctx)
-{
- SSLErr err = SSLNoErr;
-
- if(ctx == NULL) {
- return paramErr;
- }
- if (ctx->negProtocolVersion >= SSL_Version_3_0)
- ERR(err = SSLSendAlert(alert_warning, alert_close_notify, ctx));
- if (err == 0)
- ERR(err = SSLServiceWriteQueue(ctx));
- SSLChangeHdskState(ctx, SSLGracefulClose);
- if (err == SSLIOErr)
- err = SSLNoErr; /* Ignore errors related to closed streams */
- return sslErrToOsStatus(err);
-}
-
-/*
- * Determine how much data the client can be guaranteed to
- * obtain via SSLRead() without blocking or causing any low-level
- * read operations to occur.
- *
- * Implemented here because the relevant info in SSLContext (receivedDataBuffer
- * and receivedDataPos) are only used in this file.
- */
-OSStatus
-SSLGetBufferedReadSize(SSLContextRef ctx,
- size_t *bufSize) /* RETURNED */
-{
- if(ctx == NULL) {
- return paramErr;
- }
- if(ctx->receivedDataBuffer.data == NULL) {
- *bufSize = 0;
- }
- else {
- CASSERT(ctx->receivedDataBuffer.length >= ctx->receivedDataPos);
- *bufSize = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
- }
- return noErr;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: sslutil.c
-
- Contains: Misc. SSL utility functions
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: sslutil.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: sslutil.c Utility functions for encoding structures
-
- Handles encoding endian-independant wire representation of 2, 3, or 4
- byte integers.
-
- ****************************************************************** */
-
-#ifndef _SSLCTX_H_
-#include "sslctx.h"
-#endif
-
-#ifndef _SSLUTIL_H_
-#include "sslutil.h"
-#endif
-
-#ifndef _SSLALLOC_H_
-#include "sslalloc.h"
-#endif
-
-#ifndef _SSL_DEBUG_H_
-#include "sslDebug.h"
-#endif
-
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
-
-UInt32
-SSLDecodeInt(const unsigned char *p, int length)
-{ UInt32 val = 0;
- while (length--)
- val = (val << 8) | *p++;
- return val;
-}
-
-unsigned char *
-SSLEncodeInt(unsigned char *p, UInt32 value, int length)
-{ unsigned char *retVal = p + length; /* Return pointer to char after int */
- CASSERT(length > 0 && length <= 4);
- while (length--) /* Assemble backwards */
- { p[length] = (UInt8)value; /* Implicit masking to low byte */
- value >>= 8;
- }
- return retVal;
-}
-
-UInt8*
-SSLEncodeUInt64(UInt8 *p, sslUint64 value)
-{ p = SSLEncodeInt(p, value.high, 4);
- return SSLEncodeInt(p, value.low, 4);
-}
-
-
-void
-IncrementUInt64(sslUint64 *v)
-{ if (++v->low == 0) /* Must have just rolled over */
- ++v->high;
-}
-
-UInt32
-SSLGetCertificateChainLength(const SSLCertificate *c)
-{
- UInt32 rtn = 0;
-
- while (c)
- {
- rtn++;
- c = c->next;
- }
- return rtn;
-}
-
-Boolean sslIsSessionActive(const SSLContext *ctx)
-{
- CASSERT(ctx != NULL);
- switch(ctx->state) {
- case SSLUninitialized:
- case HandshakeServerUninit:
- case HandshakeClientUninit:
- case SSLGracefulClose:
- case SSLErrorClose:
- return false;
- default:
- return true;
- }
-}
-
-OSStatus sslDeleteCertificateChain(
- SSLCertificate *certs,
- SSLContext *ctx)
-{
- SSLCertificate *cert;
- SSLCertificate *nextCert;
-
- CASSERT(ctx != NULL);
- cert=certs;
- while(cert != NULL) {
- nextCert = cert->next;
- SSLFreeBuffer(&cert->derCert, &ctx->sysCtx);
- sslFree(cert);
- cert = nextCert;
- }
- return noErr;
-}
-
-#if SSL_DEBUG
-
-const char *protocolVersStr(SSLProtocolVersion prot)
-{
- switch(prot) {
- case SSL_Version_Undetermined: return "SSL_Version_Undetermined";
- case SSL_Version_3_0_With_2_0_Hello: return "SSL_Version_3_0_With_2_0_Hello";
- case SSL_Version_3_0_Only: return "SSL_Version_3_0_Only";
- case SSL_Version_2_0: return "SSL_Version_2_0";
- case SSL_Version_3_0: return "SSL_Version_3_0";
- case TLS_Version_1_0: return "TLS_Version_1_0";
- case TLS_Version_1_0_Only: return "TLS_Version_1_0_Only";
- default: sslPanic("protocolVersStr: bad prot");
- }
- return NULL; /* NOT REACHED */
-}
-
-#endif /* SSL_DEBUG */
+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: symCipher.c
-
- Contains: CDSA-based symmetric cipher module
-
- Written by: Doug Mitchell, based on Netscape SSLRef 3.0
-
- Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-/* *********************************************************************
- File: ciphers.c
-
- SSLRef 3.0 Final -- 11/19/96
-
- Copyright (c)1996 by Netscape Communications Corp.
-
- By retrieving this software you are bound by the licensing terms
- disclosed in the file "LICENSE.txt". Please read it, and if you don't
- accept the terms, delete this software.
-
- SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
- View, California <http://home.netscape.com/> and Consensus Development
- Corporation of Berkeley, California <http://www.consensus.com/>.
-
- *********************************************************************
-
- File: ciphers.c Data structures for handling supported ciphers
-
- Contains a table mapping cipherSuite values to the ciphers, MAC
- algorithms, key exchange procedures and so on that are used for that
- algorithm, in order of preference.
-
- ****************************************************************** */
-
-#include "sslctx.h"
-#include "cryptType.h"
-#include "sslDebug.h"
-#include "sslalloc.h"
-#include "appleCdsa.h"
-#include "symCipher.h"
-
-#include <Security/cssm.h>
-
-#include <string.h>
-
-/* dispose of dynamically allocated resources in a CipherContext */
-static void disposeCipherCtx(
- CipherContext *cipherCtx)
-{
- CASSERT(cipherCtx != NULL);
- if(cipherCtx->symKey != NULL) {
- CASSERT(cipherCtx->cspHand != 0);
- CSSM_FreeKey(cipherCtx->cspHand, NULL, cipherCtx->symKey, CSSM_FALSE);
- sslFree(cipherCtx->symKey);
- cipherCtx->symKey = NULL;
- }
- cipherCtx->cspHand = 0;
- if(cipherCtx->ccHand != 0) {
- CSSM_DeleteContext(cipherCtx->ccHand);
- cipherCtx->ccHand = 0;
- }
-}
-
-SSLErr CDSASymmInit(
- uint8 *key,
- uint8* iv,
- CipherContext *cipherCtx,
- SSLContext *ctx)
-{
- /*
- * Cook up a symmetric key and a CCSM_CC_HANDLE. Assumes:
- * cipherCtx->symCipher.keyAlg
- * ctx->cspHand
- * key (raw key bytes)
- * On successful exit:
- * Resulting CSSM_KEY_PTR --> cipherCtx->symKey
- * Resulting CSSM_CC_HANDLE --> cipherCtx->ccHand
- * (Currently) a copy of ctx->cspHand --> cipherCtx->cspHand
- *
- * FIXME - for now we assume that ctx->cspHand is capable of
- * using the specified algorithm, keysize, and mode. This
- * may need revisiting.
- */
-
- SSLErr serr = SSLInternalError;
- CSSM_RETURN crtn;
- const SSLSymmetricCipher *symCipher;
- CSSM_DATA ivData;
- CSSM_DATA_PTR ivDataPtr = NULL;
- CSSM_KEY_PTR symKey = NULL;
- CSSM_CC_HANDLE ccHand = 0;
- char *op;
-
- CASSERT(cipherCtx != NULL);
- CASSERT(cipherCtx->symCipher != NULL);
- CASSERT(ctx != NULL);
- if(ctx->cspHand == 0) {
- errorLog0("CDSASymmInit: NULL cspHand!\n");
- return SSLInternalError;
- }
-
- /* clean up cipherCtx */
- disposeCipherCtx(cipherCtx);
-
- /* cook up a raw key */
- symKey = sslMalloc(sizeof(CSSM_KEY));
- if(symKey == NULL) {
- return SSLMemoryErr;
- }
- serr = sslSetUpSymmKey(symKey, cipherCtx->symCipher->keyAlg,
- CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT, CSSM_TRUE,
- key, cipherCtx->symCipher->keySize);
- if(serr) {
- sslFree(symKey);
- return serr;
- }
-
- cipherCtx->symKey = symKey;
-
- /* now the crypt handle */
- symCipher = cipherCtx->symCipher;
- if(symCipher->ivSize != 0) {
- ivData.Data = iv;
- ivData.Length = symCipher->ivSize;
- ivDataPtr = &ivData;
- }
- crtn = CSSM_CSP_CreateSymmetricContext(ctx->cspHand,
- symCipher->encrAlg,
- symCipher->encrMode,
- NULL,
- symKey,
- ivDataPtr,
- symCipher->encrPad,
- 0, // Params
- &ccHand);
- if(crtn) {
- stPrintCdsaError("CSSM_CSP_CreateSymmetricContext", crtn);
- serr = SSLCryptoError;
- goto errOut;
- }
- cipherCtx->ccHand = ccHand;
-
- /* after this, each en/decrypt is merely an update */
- if(cipherCtx->encrypting) {
- crtn = CSSM_EncryptDataInit(ccHand);
- op = "CSSM_EncryptDataInit";
- }
- else {
- crtn = CSSM_DecryptDataInit(ccHand);
- op = "CSSM_DecryptDataInit";
- }
- if(crtn) {
- stPrintCdsaError("CSSM_CSP_EncryptDataInit", crtn);
- serr = SSLCryptoError;
- goto errOut;
- }
-
- /* success */
- cipherCtx->cspHand = ctx->cspHand;
- serr = SSLNoErr;
-
-errOut:
- if(serr) {
- /* dispose of the stuff we created */
- disposeCipherCtx(cipherCtx);
- }
- return serr;
-}
-
-#define REDECRYPT_DATA 0
-
-#define LOG_SYMM_DATA 0
-#if LOG_SYMM_DATA
-static void logSymmData(
- char *field,
- SSLBuffer *data,
- int maxLen)
-{
- int i;
-
- printf("%s: ", field);
- for(i=0; i<data->length; i++) {
- if(i == maxLen) {
- break;
- }
- printf("%02X", data->data[i]);
- if((i % 4) == 3) {
- printf(" ");
- }
- }
- printf("\n");
-}
-#else /* LOG_SYMM_DATA */
-#define logSymmData(f, d, l)
-#endif /* LOG_SYMM_DATA */
-
-#define IS_ALIGNED(count, blockSize) ((count % blockSize) == 0)
-
-SSLErr CDSASymmEncrypt(
- SSLBuffer src,
- SSLBuffer dest,
- CipherContext *cipherCtx,
- SSLContext *ctx)
-{
- CSSM_RETURN crtn;
- CSSM_DATA ptextData;
- CSSM_DATA ctextData;
- uint32 bytesEncrypted;
- SSLErr serr = SSLInternalError;
- uint32 origLen = dest.length;
-
- /*
- * Valid on entry:
- * cipherCtx->ccHand
- * cipherCtx->cspHand
- */
- CASSERT(ctx != NULL);
- CASSERT(cipherCtx != NULL);
- logSymmData("Symm encrypt ptext", &src, 48);
-
- /* this requirement allows us to avoid a malloc and copy */
- CASSERT(dest.length >= src.length);
-
- #if SSL_DEBUG
- {
- unsigned blockSize = cipherCtx->symCipher->blockSize;
- if(blockSize) {
- if(!IS_ALIGNED(src.length, blockSize)) {
- errorLog2("CDSASymmEncrypt: unaligned ptext (len %ld bs %d)\n",
- src.length, blockSize);
- return SSLInternalError;
- }
- if(!IS_ALIGNED(dest.length, blockSize)) {
- errorLog2("CDSASymmEncrypt: unaligned ctext (len %ld bs %d)\n",
- dest.length, blockSize);
- return SSLInternalError;
- }
- }
- }
- #endif
-
- if((cipherCtx->ccHand == 0) || (cipherCtx->cspHand == 0)) {
- errorLog0("CDSASymmEncrypt: null args\n");
- return SSLInternalError;
- }
- SSLBUF_TO_CSSM(&src, &ptextData);
- SSLBUF_TO_CSSM(&dest, &ctextData);
- crtn = CSSM_EncryptDataUpdate(cipherCtx->ccHand,
- &ptextData,
- 1,
- &ctextData,
- 1,
- &bytesEncrypted);
- if(crtn) {
- stPrintCdsaError("CSSM_EncryptDataUpdate", crtn);
- serr = SSLCryptoError;
- goto errOut;
- }
-
- if(bytesEncrypted > origLen) {
- /* should never happen, callers always give us block-aligned
- * plaintext and CSP padding is disabled. */
- errorLog2("Symmetric encrypt overflow: bytesEncrypted %ld destLen %ld\n",
- bytesEncrypted, dest.length);
- serr = SSLDataOverflow;
- goto errOut;
- }
- dest.length = bytesEncrypted;
- logSymmData("Symm encrypt ctext", &dest, 48);
- serr = SSLNoErr;
-
-errOut:
- return serr;
-}
-
-SSLErr CDSASymmDecrypt(
- SSLBuffer src,
- SSLBuffer dest,
- CipherContext *cipherCtx,
- SSLContext *ctx)
-{
- CSSM_RETURN crtn;
- CSSM_DATA ptextData = {0, NULL};
- CSSM_DATA ctextData;
- uint32 bytesDecrypted;
- SSLErr serr = SSLInternalError;
- uint32 origLen = dest.length;
-
- /*
- * Valid on entry:
- * cipherCtx->cspHand
- * cipherCtx->ccHand
- */
- CASSERT(ctx != NULL);
- CASSERT(cipherCtx != NULL);
- if((cipherCtx->ccHand == 0) || (cipherCtx->cspHand == 0)) {
- errorLog0("CDSASymmDecrypt: null args\n");
- return SSLInternalError;
- }
- /* this requirement allows us to avoid a malloc and copy */
- CASSERT(dest.length >= src.length);
-
- #if SSL_DEBUG
- {
- unsigned blockSize = cipherCtx->symCipher->blockSize;
- if(blockSize) {
- if(!IS_ALIGNED(src.length, blockSize)) {
- errorLog2("CDSASymmDecrypt: unaligned ctext (len %ld bs %d)\n",
- src.length, blockSize);
- return SSLInternalError;
- }
- if(!IS_ALIGNED(dest.length, blockSize)) {
- errorLog2("CDSASymmDecrypt: unaligned ptext (len %ld bs %d)\n",
- dest.length, blockSize);
- return SSLInternalError;
- }
- }
- }
- #endif
-
- SSLBUF_TO_CSSM(&src, &ctextData);
- SSLBUF_TO_CSSM(&dest, &ptextData);
- crtn = CSSM_DecryptDataUpdate(cipherCtx->ccHand,
- &ctextData,
- 1,
- &ptextData,
- 1,
- &bytesDecrypted);
- if(crtn) {
- stPrintCdsaError("CSSM_DecryptDataUpdate", crtn);
- serr = SSLCryptoError;
- goto errOut;
- }
-
- if(bytesDecrypted > origLen) {
- /* FIXME - can this happen? Should we remalloc? */
- errorLog2("Symmetric decrypt overflow: bytesDecrypted %ld destLen %ld\n",
- bytesDecrypted, dest.length);
- serr = SSLDataOverflow;
- goto errOut;
- }
- dest.length = bytesDecrypted;
- serr = SSLNoErr;
- logSymmData("Symm decrypt ptext(1)", &dest, 48);
-errOut:
- return serr;
-}
-
-SSLErr CDSASymmFinish(
- CipherContext *cipherCtx,
- SSLContext *ctx)
-{
- /* dispose of cipherCtx->{symKey,cspHand,ccHand} */
- disposeCipherCtx(cipherCtx);
- return SSLNoErr;
-}
-
--- /dev/null
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: symCipher.c
+
+ Contains: CDSA-based symmetric cipher module
+
+ Written by: Doug Mitchell
+
+ Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "cryptType.h"
+#include "sslDebug.h"
+#include "sslMemory.h"
+#include "appleCdsa.h"
+#include "symCipher.h"
+
+#include <Security/cssm.h>
+
+#include <string.h>
+
+/* dispose of dynamically allocated resources in a CipherContext */
+static void disposeCipherCtx(
+ CipherContext *cipherCtx)
+{
+ assert(cipherCtx != NULL);
+ if(cipherCtx->symKey != NULL) {
+ assert(cipherCtx->cspHand != 0);
+ CSSM_FreeKey(cipherCtx->cspHand, NULL, cipherCtx->symKey, CSSM_FALSE);
+ sslFree(cipherCtx->symKey);
+ cipherCtx->symKey = NULL;
+ }
+ cipherCtx->cspHand = 0;
+ if(cipherCtx->ccHand != 0) {
+ CSSM_DeleteContext(cipherCtx->ccHand);
+ cipherCtx->ccHand = 0;
+ }
+}
+
+OSStatus CDSASymmInit(
+ uint8 *key,
+ uint8* iv,
+ CipherContext *cipherCtx,
+ SSLContext *ctx)
+{
+ /*
+ * Cook up a symmetric key and a CCSM_CC_HANDLE. Assumes:
+ * cipherCtx->symCipher.keyAlg
+ * ctx->cspHand
+ * key (raw key bytes)
+ * On successful exit:
+ * Resulting CSSM_KEY_PTR --> cipherCtx->symKey
+ * Resulting CSSM_CC_HANDLE --> cipherCtx->ccHand
+ * (Currently) a copy of ctx->cspHand --> cipherCtx->cspHand
+ *
+ * FIXME - for now we assume that ctx->cspHand is capable of
+ * using the specified algorithm, keysize, and mode. This
+ * may need revisiting.
+ */
+
+ OSStatus serr = errSSLInternal;
+ CSSM_RETURN crtn;
+ const SSLSymmetricCipher *symCipher;
+ CSSM_DATA ivData;
+ CSSM_DATA_PTR ivDataPtr = NULL;
+ CSSM_KEY_PTR symKey = NULL;
+ CSSM_CC_HANDLE ccHand = 0;
+ char *op;
+
+ assert(cipherCtx != NULL);
+ assert(cipherCtx->symCipher != NULL);
+ assert(ctx != NULL);
+ if(ctx->cspHand == 0) {
+ sslErrorLog("CDSASymmInit: NULL cspHand!\n");
+ return errSSLInternal;
+ }
+
+ /* clean up cipherCtx */
+ disposeCipherCtx(cipherCtx);
+
+ /* cook up a raw key */
+ symKey = (CSSM_KEY_PTR)sslMalloc(sizeof(CSSM_KEY));
+ if(symKey == NULL) {
+ return memFullErr;
+ }
+ serr = sslSetUpSymmKey(symKey, cipherCtx->symCipher->keyAlg,
+ CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT, CSSM_TRUE,
+ key, cipherCtx->symCipher->keySize);
+ if(serr) {
+ sslFree(symKey);
+ return serr;
+ }
+
+ cipherCtx->symKey = symKey;
+
+ /* now the crypt handle */
+ symCipher = cipherCtx->symCipher;
+ if(symCipher->ivSize != 0) {
+ ivData.Data = iv;
+ ivData.Length = symCipher->ivSize;
+ ivDataPtr = &ivData;
+ }
+ crtn = CSSM_CSP_CreateSymmetricContext(ctx->cspHand,
+ symCipher->encrAlg,
+ symCipher->encrMode,
+ NULL,
+ symKey,
+ ivDataPtr,
+ symCipher->encrPad,
+ 0, // Params
+ &ccHand);
+ if(crtn) {
+ stPrintCdsaError("CSSM_CSP_CreateSymmetricContext", crtn);
+ serr = errSSLCrypto;
+ goto errOut;
+ }
+ cipherCtx->ccHand = ccHand;
+
+ /* after this, each en/decrypt is merely an update */
+ if(cipherCtx->encrypting) {
+ crtn = CSSM_EncryptDataInit(ccHand);
+ op = "CSSM_EncryptDataInit";
+ }
+ else {
+ crtn = CSSM_DecryptDataInit(ccHand);
+ op = "CSSM_DecryptDataInit";
+ }
+ if(crtn) {
+ stPrintCdsaError("CSSM_CSP_EncryptDataInit", crtn);
+ serr = errSSLCrypto;
+ goto errOut;
+ }
+
+ /* success */
+ cipherCtx->cspHand = ctx->cspHand;
+ serr = noErr;
+
+errOut:
+ if(serr) {
+ /* dispose of the stuff we created */
+ disposeCipherCtx(cipherCtx);
+ }
+ return serr;
+}
+
+#define REDECRYPT_DATA 0
+
+#define LOG_SYMM_DATA 0
+#if LOG_SYMM_DATA
+static void logSymmData(
+ char *field,
+ SSLBuffer *data,
+ int maxLen)
+{
+ int i;
+
+ printf("%s: ", field);
+ for(i=0; i<data->length; i++) {
+ if(i == maxLen) {
+ break;
+ }
+ printf("%02X", data->data[i]);
+ if((i % 4) == 3) {
+ printf(" ");
+ }
+ }
+ printf("\n");
+}
+#else /* LOG_SYMM_DATA */
+#define logSymmData(f, d, l)
+#endif /* LOG_SYMM_DATA */
+
+#define IS_ALIGNED(count, blockSize) ((count % blockSize) == 0)
+
+OSStatus CDSASymmEncrypt(
+ SSLBuffer src,
+ SSLBuffer dest,
+ CipherContext *cipherCtx,
+ SSLContext *ctx)
+{
+ CSSM_RETURN crtn;
+ CSSM_DATA ptextData;
+ CSSM_DATA ctextData;
+ uint32 bytesEncrypted;
+ OSStatus serr = errSSLInternal;
+ uint32 origLen = dest.length;
+
+ /*
+ * Valid on entry:
+ * cipherCtx->ccHand
+ * cipherCtx->cspHand
+ */
+ assert(ctx != NULL);
+ assert(cipherCtx != NULL);
+ logSymmData("Symm encrypt ptext", &src, 48);
+
+ /* this requirement allows us to avoid a malloc and copy */
+ assert(dest.length >= src.length);
+
+ #if SSL_DEBUG
+ {
+ unsigned blockSize = cipherCtx->symCipher->blockSize;
+ if(blockSize) {
+ if(!IS_ALIGNED(src.length, blockSize)) {
+ sslErrorLog("CDSASymmEncrypt: unaligned ptext (len %ld bs %d)\n",
+ src.length, blockSize);
+ return errSSLInternal;
+ }
+ if(!IS_ALIGNED(dest.length, blockSize)) {
+ sslErrorLog("CDSASymmEncrypt: unaligned ctext (len %ld bs %d)\n",
+ dest.length, blockSize);
+ return errSSLInternal;
+ }
+ }
+ }
+ #endif
+
+ if((cipherCtx->ccHand == 0) || (cipherCtx->cspHand == 0)) {
+ sslErrorLog("CDSASymmEncrypt: null args\n");
+ return errSSLInternal;
+ }
+ SSLBUF_TO_CSSM(&src, &ptextData);
+ SSLBUF_TO_CSSM(&dest, &ctextData);
+ crtn = CSSM_EncryptDataUpdate(cipherCtx->ccHand,
+ &ptextData,
+ 1,
+ &ctextData,
+ 1,
+ &bytesEncrypted);
+ if(crtn) {
+ stPrintCdsaError("CSSM_EncryptDataUpdate", crtn);
+ serr = errSSLCrypto;
+ goto errOut;
+ }
+
+ if(bytesEncrypted > origLen) {
+ /* should never happen, callers always give us block-aligned
+ * plaintext and CSP padding is disabled. */
+ sslErrorLog("Symmetric encrypt overflow: bytesEncrypted %ld destLen %ld\n",
+ bytesEncrypted, dest.length);
+ serr = errSSLCrypto;
+ goto errOut;
+ }
+ dest.length = bytesEncrypted;
+ logSymmData("Symm encrypt ctext", &dest, 48);
+ serr = noErr;
+
+errOut:
+ return serr;
+}
+
+OSStatus CDSASymmDecrypt(
+ SSLBuffer src,
+ SSLBuffer dest,
+ CipherContext *cipherCtx,
+ SSLContext *ctx)
+{
+ CSSM_RETURN crtn;
+ CSSM_DATA ptextData = {0, NULL};
+ CSSM_DATA ctextData;
+ uint32 bytesDecrypted;
+ OSStatus serr = errSSLInternal;
+ uint32 origLen = dest.length;
+
+ /*
+ * Valid on entry:
+ * cipherCtx->cspHand
+ * cipherCtx->ccHand
+ */
+ assert(ctx != NULL);
+ assert(cipherCtx != NULL);
+ if((cipherCtx->ccHand == 0) || (cipherCtx->cspHand == 0)) {
+ sslErrorLog("CDSASymmDecrypt: null args\n");
+ return errSSLInternal;
+ }
+ /* this requirement allows us to avoid a malloc and copy */
+ assert(dest.length >= src.length);
+
+ #if SSL_DEBUG
+ {
+ unsigned blockSize = cipherCtx->symCipher->blockSize;
+ if(blockSize) {
+ if(!IS_ALIGNED(src.length, blockSize)) {
+ sslErrorLog("CDSASymmDecrypt: unaligned ctext (len %ld bs %d)\n",
+ src.length, blockSize);
+ return errSSLInternal;
+ }
+ if(!IS_ALIGNED(dest.length, blockSize)) {
+ sslErrorLog("CDSASymmDecrypt: unaligned ptext (len %ld bs %d)\n",
+ dest.length, blockSize);
+ return errSSLInternal;
+ }
+ }
+ }
+ #endif
+
+ SSLBUF_TO_CSSM(&src, &ctextData);
+ SSLBUF_TO_CSSM(&dest, &ptextData);
+ crtn = CSSM_DecryptDataUpdate(cipherCtx->ccHand,
+ &ctextData,
+ 1,
+ &ptextData,
+ 1,
+ &bytesDecrypted);
+ if(crtn) {
+ stPrintCdsaError("CSSM_DecryptDataUpdate", crtn);
+ serr = errSSLCrypto;
+ goto errOut;
+ }
+
+ if(bytesDecrypted > origLen) {
+ /* FIXME - can this happen? Should we remalloc? */
+ sslErrorLog("Symmetric decrypt overflow: bytesDecrypted %ld destLen %ld\n",
+ bytesDecrypted, dest.length);
+ serr = errSSLCrypto;
+ goto errOut;
+ }
+ dest.length = bytesDecrypted;
+ serr = noErr;
+ logSymmData("Symm decrypt ptext(1)", &dest, 48);
+errOut:
+ return serr;
+}
+
+OSStatus CDSASymmFinish(
+ CipherContext *cipherCtx,
+ SSLContext *ctx)
+{
+ /* dispose of cipherCtx->{symKey,cspHand,ccHand} */
+ disposeCipherCtx(cipherCtx);
+ return noErr;
+}
+
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: tls1Callouts.c
-
- Contains: TLSv1-specific routines for SslTlsCallouts.
-
- Written by: Doug Mitchell
-*/
-
-#include "tls_ssl.h"
-#include "sslerrs.h"
-#include "sslalloc.h"
-#include "sslutil.h"
-#include "digests.h"
-#include "sslalert.h"
-#include "sslDebug.h"
-#include <assert.h>
-#include <strings.h>
-
-#define TLS_ENC_DEBUG 0
-#if TLS_ENC_DEBUG
-#define tlsDebug(format, args...) printf(format , ## args)
-static void tlsDump(const char *name, void *b, unsigned len)
-{
- unsigned char *cp = (unsigned char *)b;
- unsigned i, dex;
-
- printf("%s\n", name);
- for(dex=0; dex<len; dex++) {
- i = cp[dex];
- printf("%02X ", i);
- if((dex % 16) == 15) {
- printf("\n");
- }
- }
- printf("\n");
-}
-
-#else
-#define tlsDebug(s, ...)
-#define tlsDump(name, b, len)
-#endif /* TLS_ENC_DEBUG */
-
-#pragma *** PRF label strings ***
-/*
- * Note we could optimize away a bunch of mallocs and frees if we, like openSSL,
- * just mallocd buffers for inputs to tlsPRF() on the stack, with "known" max
- * values for all of the inputs.
- *
- * At least we hard-code string lengths here instead of calling strlen at runtime...
- */
-#define PLS_MASTER_SECRET "master secret"
-#define PLS_MASTER_SECRET_LEN 13
-#define PLS_KEY_EXPAND "key expansion"
-#define PLS_KEY_EXPAND_LEN 13
-#define PLS_CLIENT_FINISH "client finished"
-#define PLS_CLIENT_FINISH_LEN 15
-#define PLS_SERVER_FINISH "server finished"
-#define PLS_SERVER_FINISH_LEN 15
-#define PLS_EXPORT_CLIENT_WRITE "client write key"
-#define PLS_EXPORT_CLIENT_WRITE_LEN 16
-#define PLS_EXPORT_SERVER_WRITE "server write key"
-#define PLS_EXPORT_SERVER_WRITE_LEN 16
-#define PLS_EXPORT_IV_BLOCK "IV block"
-#define PLS_EXPORT_IV_BLOCK_LEN 8
-
-#pragma mark *** private functions ***
-
-/*
- * P_Hash function defined in RFC2246, section 5.
- */
-static SSLErr tlsPHash(
- SSLContext *ctx,
- const HMACReference *hmac, // &TlsHmacSHA1, TlsHmacMD5
- const unsigned char *secret,
- unsigned secretLen,
- unsigned char *seed,
- unsigned seedLen,
- unsigned char *out, // mallocd by caller, size >= outLen
- unsigned outLen) // desired output size
-{
- unsigned char aSubI[TLS_HMAC_MAX_SIZE]; /* A(i) */
- unsigned char digest[TLS_HMAC_MAX_SIZE];
- HMACContextRef hmacCtx;
- SSLErr serr;
- unsigned digestLen = hmac->macSize;
-
- serr = hmac->alloc(hmac, ctx, secret, secretLen, &hmacCtx);
- if(serr) {
- return serr;
- }
-
- /* A(0) = seed */
- /* A(1) := HMAC_hash(secret, seed) */
- serr = hmac->hmac(hmacCtx, seed, seedLen, aSubI, &digestLen);
- if(serr) {
- goto fail;
- }
- assert(digestLen = hmac->macSize);
-
- /* starting at loopNum 1... */
- for (;;) {
- /*
- * This loop's chunk = HMAC_hash(secret, A(loopNum) + seed))
- */
- serr = hmac->init(hmacCtx);
- if(serr) {
- break;
- }
- serr = hmac->update(hmacCtx, aSubI, digestLen);
- if(serr) {
- break;
- }
- serr = hmac->update(hmacCtx, seed, seedLen);
- if(serr) {
- break;
- }
- serr = hmac->final(hmacCtx, digest, &digestLen);
- if(serr) {
- break;
- }
- assert(digestLen = hmac->macSize);
-
- if(outLen <= digestLen) {
- /* last time, possible partial digest */
- memmove(out, digest, outLen);
- break;
- }
-
- memmove(out, digest, digestLen);
- out += digestLen;
- outLen -= digestLen;
-
- /*
- * A(i) = HMAC_hash(secret, A(i-1))
- * Note there is a possible optimization involving obtaining this
- * hmac by cloning the state of hmacCtx above after updating with
- * aSubI, and getting the final version of that here. However CDSA
- * does not support cloning of a MAC context (only for digest contexts).
- */
- serr = hmac->hmac(hmacCtx, aSubI, digestLen,
- aSubI, &digestLen);
- if(serr) {
- break;
- }
- assert(digestLen = hmac->macSize);
- }
-fail:
- hmac->free(hmacCtx);
- memset(aSubI, 0, TLS_HMAC_MAX_SIZE);
- memset(digest, 0, TLS_HMAC_MAX_SIZE);
- return serr;
-}
-
-/*
- * The TLS pseudorandom function, defined in RFC2246, section 5.
- * This takes as its input a secret block, a label, and a seed, and produces
- * a caller-specified length of pseudorandom data.
- *
- * Optimization TBD: make label optional, avoid malloc and two copies if it's
- * not there, so callers can take advantage of fixed-size seeds.
- */
-static SSLErr tlsPRF(
- SSLContext *ctx,
- const unsigned char *secret,
- unsigned secretLen,
- const unsigned char *label, // optional, NULL implies that seed contains
- // the label
- unsigned labelLen,
- const unsigned char *seed,
- unsigned seedLen,
- unsigned char *out, // mallocd by called, length >= outLen
- unsigned outLen)
-{
- SSLErr serr = SSLInternalError;
- const unsigned char *S1, *S2; // the two seeds
- unsigned sLen; // effective length of each seed
- unsigned char *labelSeed = NULL; // label + seed, passed to tlsPHash
- unsigned labelSeedLen;
- unsigned char *tmpOut = NULL; // output of P_SHA1
- unsigned i;
-
- /* two seeds for tlsPHash */
- sLen = secretLen / 2; // for partitioning
- S1 = secret;
- S2 = &secret[sLen];
- sLen += (secretLen & 1); // secret length odd, increment effective size
-
- if(label != NULL) {
- /* concatenate label and seed */
- labelSeedLen = labelLen + seedLen;
- labelSeed = sslMalloc(labelSeedLen);
- if(labelSeed == NULL) {
- return SSLMemoryErr;
- }
- memmove(labelSeed, label, labelLen);
- memmove(labelSeed + labelLen, seed, seedLen);
- }
- else {
- /* fast track - just use seed as is */
- labelSeed = (unsigned char *)seed;
- labelSeedLen = seedLen;
- }
-
- /* temporary output for SHA1, to be XORd with MD5 */
- tmpOut = sslMalloc(outLen);
- if(tmpOut == NULL) {
- serr = SSLMemoryErr;
- goto fail;
- }
- serr = tlsPHash(ctx, &TlsHmacMD5, S1, sLen, labelSeed, labelSeedLen,
- out, outLen);
- if(serr) {
- goto fail;
- }
- serr = tlsPHash(ctx, &TlsHmacSHA1, S2, sLen, labelSeed, labelSeedLen,
- tmpOut, outLen);
- if(serr) {
- goto fail;
- }
-
- /* XOR together to get final result */
- for(i=0; i<outLen; i++) {
- out[i] ^= tmpOut[i];
- }
- serr = SSLNoErr;
-
-fail:
- if((labelSeed != NULL) && (label != NULL)) {
- sslFree(labelSeed);
- }
- if(tmpOut != NULL) {
- sslFree(tmpOut);
- }
- return serr;
-}
-
-/* not needed; encrypt/encode is the same for both protocols as long as
- * we don't use the "variable length padding" feature. */
-#if 0
-static SSLErr tls1WriteRecord(
- SSLRecord rec,
- SSLContext *ctx)
-{
- assert(0);
- return SSLUnsupportedErr;
-}
-#endif
-
-static SSLErr tls1DecryptRecord(
- UInt8 type,
- SSLBuffer *payload,
- SSLContext *ctx)
-{
- SSLErr err;
- SSLBuffer content;
-
- if ((ctx->readCipher.symCipher->blockSize > 0) &&
- ((payload->length % ctx->readCipher.symCipher->blockSize) != 0)) {
- SSLFatalSessionAlert(alert_unexpected_message, ctx);
- return SSLProtocolErr;
- }
-
- /* Decrypt in place */
- if ((err = ctx->readCipher.symCipher->decrypt(*payload,
- *payload,
- &ctx->readCipher,
- ctx)) != 0)
- { SSLFatalSessionAlert(alert_close_notify, ctx);
- return err;
- }
-
- /* Locate content within decrypted payload */
- content.data = payload->data;
- content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
- if (ctx->readCipher.symCipher->blockSize > 0) {
- /* for TLSv1, padding can be anywhere from 0 to 255 bytes */
- UInt8 padSize = payload->data[payload->length - 1];
- UInt8 *padChars;
-
- /* verify that all padding bytes are equal - WARNING - OpenSSL code
- * has a special case here dealing with some kind of bug related to
- * even size packets...beware... */
- if(padSize > payload->length) {
- SSLFatalSessionAlert(alert_unexpected_message, ctx);
- errorLog1("tls1DecryptRecord: bad padding length (%d)\n",
- (unsigned)payload->data[payload->length - 1]);
- return SSLProtocolErr;
- }
- padChars = payload->data + payload->length - padSize;
- while(padChars < (payload->data + payload->length)) {
- if(*padChars++ != padSize) {
- SSLFatalSessionAlert(alert_unexpected_message, ctx);
- errorLog0("tls1DecryptRecord: bad padding value\n");
- return SSLProtocolErr;
- }
- }
- /* Remove block size padding and its one-byte length */
- content.length -= (1 + padSize);
- }
-
- /* Verify MAC on payload */
- if (ctx->readCipher.macRef->hash->digestSize > 0)
- /* Optimize away MAC for null case */
- if ((err = SSLVerifyMac(type, content,
- payload->data + content.length, ctx)) != 0)
- { SSLFatalSessionAlert(alert_bad_record_mac, ctx);
- return err;
- }
-
- *payload = content; /* Modify payload buffer to indicate content length */
-
- return SSLNoErr;
-}
-
-/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
-static SSLErr tls1InitMac (
- CipherContext *cipherCtx, // macRef, macSecret valid on entry
- // macCtx valid on return
- SSLContext *ctx)
-{
- const HMACReference *hmac;
- SSLErr serr;
-
- assert(cipherCtx->macRef != NULL);
- hmac = cipherCtx->macRef->hmac;
- assert(hmac != NULL);
-
- if(cipherCtx->macCtx.hmacCtx != NULL) {
- hmac->free(cipherCtx->macCtx.hmacCtx);
- cipherCtx->macCtx.hmacCtx = NULL;
- }
- serr = hmac->alloc(hmac, ctx, cipherCtx->macSecret,
- cipherCtx->macRef->hmac->macSize, &cipherCtx->macCtx.hmacCtx);
-
- /* mac secret now stored in macCtx.hmacCtx, delete it from cipherCtx */
- memset(cipherCtx->macSecret, 0, sizeof(cipherCtx->macSecret));
- return serr;
-}
-
-static SSLErr tls1FreeMac (
- CipherContext *cipherCtx)
-{
- /* this can be called on a completely zeroed out CipherContext... */
- if(cipherCtx->macRef == NULL) {
- return SSLNoErr;
- }
- assert(cipherCtx->macRef->hmac != NULL);
-
- if(cipherCtx->macCtx.hmacCtx != NULL) {
- cipherCtx->macRef->hmac->free(cipherCtx->macCtx.hmacCtx);
- cipherCtx->macCtx.hmacCtx = NULL;
- }
- return SSLNoErr;
-}
-
-/*
- * mac = HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
- * TLSCompressed.version + TLSCompressed.length +
- * TLSCompressed.fragment));
- */
-
-/* sequence, type, version, length */
-#define HDR_LENGTH (8 + 1 + 2 + 2)
-SSLErr tls1ComputeMac (
- UInt8 type,
- SSLBuffer data,
- SSLBuffer mac, // caller mallocs data
- CipherContext *cipherCtx, // assumes macCtx, macRef
- sslUint64 seqNo,
- SSLContext *ctx)
-{
- unsigned char hdr[HDR_LENGTH];
- unsigned char *p;
- HMACContextRef hmacCtx;
- SSLErr serr;
- const HMACReference *hmac;
- unsigned macLength;
-
- assert(cipherCtx != NULL);
- assert(cipherCtx->macRef != NULL);
- hmac = cipherCtx->macRef->hmac;
- assert(hmac != NULL);
- hmacCtx = cipherCtx->macCtx.hmacCtx; // may be NULL, for null cipher
-
- serr = hmac->init(hmacCtx);
- if(serr) {
- goto fail;
- }
- p = SSLEncodeUInt64(hdr, seqNo);
- *p++ = type;
- *p++ = TLS_Version_1_0 >> 8;
- *p++ = TLS_Version_1_0 & 0xff;
- *p++ = data.length >> 8;
- *p = data.length & 0xff;
- serr = hmac->update(hmacCtx, hdr, HDR_LENGTH);
- if(serr) {
- goto fail;
- }
- serr = hmac->update(hmacCtx, data.data, data.length);
- if(serr) {
- goto fail;
- }
- macLength = mac.length;
- serr = hmac->final(hmacCtx, mac.data, &macLength);
- if(serr) {
- goto fail;
- }
- mac.length = macLength;
-fail:
- return serr;
-}
-
-/*
- * On input, the following are valid:
- * MasterSecret[48]
- * ClientHello.random[32]
- * ServerHello.random[32]
- *
- * key_block = PRF(SecurityParameters.master_secret,
- * "key expansion",
- * SecurityParameters.server_random +
- * SecurityParameters.client_random);
- */
-
-#define GKM_SEED_LEN (PLS_KEY_EXPAND_LEN + (2 * SSL_CLIENT_SRVR_RAND_SIZE))
-
-SSLErr tls1GenerateKeyMaterial (
- SSLBuffer key, // caller mallocs and specifies length of
- // required key material here
- SSLContext *ctx)
-{
- unsigned char seedBuf[GKM_SEED_LEN];
- SSLErr serr;
-
- /* use optimized label-less PRF */
- memmove(seedBuf, PLS_KEY_EXPAND, PLS_KEY_EXPAND_LEN);
- memmove(seedBuf + PLS_KEY_EXPAND_LEN, ctx->serverRandom,
- SSL_CLIENT_SRVR_RAND_SIZE);
- memmove(seedBuf + PLS_KEY_EXPAND_LEN + SSL_CLIENT_SRVR_RAND_SIZE,
- ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
- serr = tlsPRF(ctx,
- ctx->masterSecret,
- SSL_MASTER_SECRET_SIZE,
- NULL, // no label
- 0,
- seedBuf,
- GKM_SEED_LEN,
- key.data, // destination
- key.length);
- tlsDump("key expansion", key.data, key.length);
- return serr;
-}
-
-/*
- * final_client_write_key =
- * PRF(SecurityParameters.client_write_key,
- * "client write key",
- * SecurityParameters.client_random +
- * SecurityParameters.server_random);
- * final_server_write_key =
- * PRF(SecurityParameters.server_write_key,
- * "server write key",
- * SecurityParameters.client_random +
- * SecurityParameters.server_random);
- *
- * iv_block = PRF("", "IV block", SecurityParameters.client_random +
- * SecurityParameters.server_random);
- *
- * iv_block is broken up into:
- *
- * client_write_IV[SecurityParameters.IV_size]
- * server_write_IV[SecurityParameters.IV_size]
- */
-SSLErr tls1GenerateExportKeyAndIv (
- SSLContext *ctx, // clientRandom, serverRandom valid
- const SSLBuffer clientWriteKey,
- const SSLBuffer serverWriteKey,
- SSLBuffer finalClientWriteKey, // RETURNED, mallocd by caller
- SSLBuffer finalServerWriteKey, // RETURNED, mallocd by caller
- SSLBuffer finalClientIV, // RETURNED, mallocd by caller
- SSLBuffer finalServerIV) // RETURNED, mallocd by caller
-{
- unsigned char randBuf[2 * SSL_CLIENT_SRVR_RAND_SIZE];
- SSLErr serr;
- unsigned char *ivBlock;
- char *nullKey = "";
-
- /* all three PRF calls use the same seed */
- memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
- memmove(randBuf + SSL_CLIENT_SRVR_RAND_SIZE,
- ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
-
- serr = tlsPRF(ctx,
- clientWriteKey.data,
- clientWriteKey.length,
- PLS_EXPORT_CLIENT_WRITE,
- PLS_EXPORT_CLIENT_WRITE_LEN,
- randBuf,
- 2 * SSL_CLIENT_SRVR_RAND_SIZE,
- finalClientWriteKey.data, // destination
- finalClientWriteKey.length);
- if(serr) {
- return serr;
- }
- serr = tlsPRF(ctx,
- serverWriteKey.data,
- serverWriteKey.length,
- PLS_EXPORT_SERVER_WRITE,
- PLS_EXPORT_SERVER_WRITE_LEN,
- randBuf,
- 2 * SSL_CLIENT_SRVR_RAND_SIZE,
- finalServerWriteKey.data, // destination
- finalServerWriteKey.length);
- if(serr) {
- return serr;
- }
- if((finalClientIV.length == 0) && (finalServerIV.length == 0)) {
- /* skip remainder as optimization */
- return SSLNoErr;
- }
- ivBlock = sslMalloc(finalClientIV.length + finalServerIV.length);
- if(ivBlock == NULL) {
- return SSLMemoryErr;
- }
- serr = tlsPRF(ctx,
- nullKey,
- 0,
- PLS_EXPORT_IV_BLOCK,
- PLS_EXPORT_IV_BLOCK_LEN,
- randBuf,
- 2 * SSL_CLIENT_SRVR_RAND_SIZE,
- ivBlock, // destination
- finalClientIV.length + finalServerIV.length);
- if(serr) {
- goto done;
- }
- memmove(finalClientIV.data, ivBlock, finalClientIV.length);
- memmove(finalServerIV.data, ivBlock + finalClientIV.length, finalServerIV.length);
-done:
- sslFree(ivBlock);
- return serr;
-}
-
-/*
- * On entry: clientRandom, serverRandom, preMasterSecret valid
- * On return: masterSecret valid
- *
- * master_secret = PRF(pre_master_secret, "master secret",
- * ClientHello.random + ServerHello.random)
- * [0..47];
- */
-
-SSLErr tls1GenerateMasterSecret (
- SSLContext *ctx)
-{
- unsigned char randBuf[2 * SSL_CLIENT_SRVR_RAND_SIZE];
- SSLErr serr;
-
- memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
- memmove(randBuf + SSL_CLIENT_SRVR_RAND_SIZE,
- ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
- serr = tlsPRF(ctx,
- ctx->preMasterSecret.data,
- ctx->preMasterSecret.length,
- PLS_MASTER_SECRET,
- PLS_MASTER_SECRET_LEN,
- randBuf,
- 2 * SSL_CLIENT_SRVR_RAND_SIZE,
- ctx->masterSecret, // destination
- SSL_MASTER_SECRET_SIZE);
- tlsDump("master secret", ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
- return serr;
-}
-
-/*
- * Given digests contexts representing the running total of all handshake messages,
- * calculate mac for "finished" message.
- *
- * verify_data = 12 bytes =
- * PRF(master_secret, finished_label, MD5(handshake_messages) +
- * SHA-1(handshake_messages)) [0..11];
- */
-SSLErr tls1ComputeFinishedMac (
- SSLContext *ctx,
- SSLBuffer finished, // output - mallocd by caller
- SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
- SSLBuffer md5MsgState, // ditto
- Boolean isServer)
-{
- unsigned char digests[SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN];
- SSLBuffer digBuf;
- unsigned char *finLabel;
- unsigned finLabelLen;
- SSLErr serr;
-
- if(isServer) {
- finLabel = PLS_SERVER_FINISH;
- finLabelLen = PLS_SERVER_FINISH_LEN;
- }
- else {
- finLabel = PLS_CLIENT_FINISH;
- finLabelLen = PLS_CLIENT_FINISH_LEN;
- }
-
- /* concatenate two digest results */
- digBuf.data = digests;
- digBuf.length = SSL_MD5_DIGEST_LEN;
- serr = SSLHashMD5.final(md5MsgState, digBuf);
- if(serr) {
- return serr;
- }
- digBuf.data += SSL_MD5_DIGEST_LEN;
- digBuf.length = SSL_SHA1_DIGEST_LEN;
- serr = SSLHashSHA1.final(shaMsgState, digBuf);
- if(serr) {
- return serr;
- }
- return tlsPRF(ctx,
- ctx->masterSecret,
- SSL_MASTER_SECRET_SIZE,
- finLabel,
- finLabelLen,
- digests,
- SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN,
- finished.data, // destination
- finished.length);
-}
-
-/*
- * This one is trivial.
- *
- * mac := MD5(handshake_messages) + SHA(handshake_messages);
- *
- * I don't know why this one doesn't use an HMAC or the master secret (as SSLv3
- * does).
- */
-SSLErr tls1ComputeCertVfyMac (
- SSLContext *ctx,
- SSLBuffer finished, // output - mallocd by caller
- SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
- SSLBuffer md5MsgState) // ditto
-{
- SSLBuffer digBuf;
- SSLErr serr;
-
- assert(finished.length == (SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN));
- digBuf.data = finished.data;
- digBuf.length = SSL_MD5_DIGEST_LEN;
- serr = SSLHashMD5.final(md5MsgState, digBuf);
- if(serr) {
- return serr;
- }
- digBuf.data = finished.data + SSL_MD5_DIGEST_LEN;
- digBuf.length = SSL_SHA1_DIGEST_LEN;
- return SSLHashSHA1.final(shaMsgState, digBuf);
-}
-
-const SslTlsCallouts Tls1Callouts = {
- tls1DecryptRecord,
- ssl3WriteRecord,
- tls1InitMac,
- tls1FreeMac,
- tls1ComputeMac,
- tls1GenerateKeyMaterial,
- tls1GenerateExportKeyAndIv,
- tls1GenerateMasterSecret,
- tls1ComputeFinishedMac,
- tls1ComputeCertVfyMac
-};
--- /dev/null
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: tls1Callouts.c
+
+ Contains: TLSv1-specific routines for SslTlsCallouts.
+
+ Written by: Doug Mitchell
+*/
+
+#include "tls_ssl.h"
+#include "sslMemory.h"
+#include "sslUtils.h"
+#include "sslDigests.h"
+#include "sslAlertMessage.h"
+#include "sslDebug.h"
+#include <assert.h>
+#include <strings.h>
+
+#define TLS_ENC_DEBUG 0
+#if TLS_ENC_DEBUG
+#define tlsDebug(format, args...) printf(format , ## args)
+static void tlsDump(const char *name, void *b, unsigned len)
+{
+ unsigned char *cp = (unsigned char *)b;
+ unsigned i, dex;
+
+ printf("%s\n", name);
+ for(dex=0; dex<len; dex++) {
+ i = cp[dex];
+ printf("%02X ", i);
+ if((dex % 16) == 15) {
+ printf("\n");
+ }
+ }
+ printf("\n");
+}
+
+#else
+#define tlsDebug(s, ...)
+#define tlsDump(name, b, len)
+#endif /* TLS_ENC_DEBUG */
+
+#pragma *** PRF label strings ***
+/*
+ * Note we could optimize away a bunch of mallocs and frees if we, like openSSL,
+ * just mallocd buffers for inputs to SSLInternal_PRF() on the stack,
+ * with "known" max values for all of the inputs.
+ *
+ * At least we hard-code string lengths here instead of calling strlen at runtime...
+ */
+#define PLS_MASTER_SECRET "master secret"
+#define PLS_MASTER_SECRET_LEN 13
+#define PLS_KEY_EXPAND "key expansion"
+#define PLS_KEY_EXPAND_LEN 13
+#define PLS_CLIENT_FINISH "client finished"
+#define PLS_CLIENT_FINISH_LEN 15
+#define PLS_SERVER_FINISH "server finished"
+#define PLS_SERVER_FINISH_LEN 15
+#define PLS_EXPORT_CLIENT_WRITE "client write key"
+#define PLS_EXPORT_CLIENT_WRITE_LEN 16
+#define PLS_EXPORT_SERVER_WRITE "server write key"
+#define PLS_EXPORT_SERVER_WRITE_LEN 16
+#define PLS_EXPORT_IV_BLOCK "IV block"
+#define PLS_EXPORT_IV_BLOCK_LEN 8
+
+#pragma mark *** private functions ***
+
+/*
+ * P_Hash function defined in RFC2246, section 5.
+ */
+static OSStatus tlsPHash(
+ SSLContext *ctx,
+ const HMACReference *hmac, // &TlsHmacSHA1, TlsHmacMD5
+ const unsigned char *secret,
+ unsigned secretLen,
+ unsigned char *seed,
+ unsigned seedLen,
+ unsigned char *out, // mallocd by caller, size >= outLen
+ unsigned outLen) // desired output size
+{
+ unsigned char aSubI[TLS_HMAC_MAX_SIZE]; /* A(i) */
+ unsigned char digest[TLS_HMAC_MAX_SIZE];
+ HMACContextRef hmacCtx;
+ OSStatus serr;
+ unsigned digestLen = hmac->macSize;
+
+ serr = hmac->alloc(hmac, ctx, secret, secretLen, &hmacCtx);
+ if(serr) {
+ return serr;
+ }
+
+ /* A(0) = seed */
+ /* A(1) := HMAC_hash(secret, seed) */
+ serr = hmac->hmac(hmacCtx, seed, seedLen, aSubI, &digestLen);
+ if(serr) {
+ goto fail;
+ }
+ assert(digestLen = hmac->macSize);
+
+ /* starting at loopNum 1... */
+ for (;;) {
+ /*
+ * This loop's chunk = HMAC_hash(secret, A(loopNum) + seed))
+ */
+ serr = hmac->init(hmacCtx);
+ if(serr) {
+ break;
+ }
+ serr = hmac->update(hmacCtx, aSubI, digestLen);
+ if(serr) {
+ break;
+ }
+ serr = hmac->update(hmacCtx, seed, seedLen);
+ if(serr) {
+ break;
+ }
+ serr = hmac->final(hmacCtx, digest, &digestLen);
+ if(serr) {
+ break;
+ }
+ assert(digestLen = hmac->macSize);
+
+ if(outLen <= digestLen) {
+ /* last time, possible partial digest */
+ memmove(out, digest, outLen);
+ break;
+ }
+
+ memmove(out, digest, digestLen);
+ out += digestLen;
+ outLen -= digestLen;
+
+ /*
+ * A(i) = HMAC_hash(secret, A(i-1))
+ * Note there is a possible optimization involving obtaining this
+ * hmac by cloning the state of hmacCtx above after updating with
+ * aSubI, and getting the final version of that here. However CDSA
+ * does not support cloning of a MAC context (only for digest contexts).
+ */
+ serr = hmac->hmac(hmacCtx, aSubI, digestLen,
+ aSubI, &digestLen);
+ if(serr) {
+ break;
+ }
+ assert(digestLen = hmac->macSize);
+ }
+fail:
+ hmac->free(hmacCtx);
+ memset(aSubI, 0, TLS_HMAC_MAX_SIZE);
+ memset(digest, 0, TLS_HMAC_MAX_SIZE);
+ return serr;
+}
+
+/*
+ * The TLS pseudorandom function, defined in RFC2246, section 5.
+ * This takes as its input a secret block, a label, and a seed, and produces
+ * a caller-specified length of pseudorandom data.
+ *
+ * Optimization TBD: make label optional, avoid malloc and two copies if it's
+ * not there, so callers can take advantage of fixed-size seeds.
+ */
+OSStatus SSLInternal_PRF(
+ SSLContext *ctx,
+ const void *vsecret,
+ size_t secretLen,
+ const void *label, // optional, NULL implies that seed contains
+ // the label
+ size_t labelLen,
+ const void *seed,
+ size_t seedLen,
+ void *vout, // mallocd by caller, length >= outLen
+ size_t outLen)
+{
+ OSStatus serr = errSSLInternal;
+ const unsigned char *S1, *S2; // the two seeds
+ unsigned sLen; // effective length of each seed
+ unsigned char *labelSeed = NULL; // label + seed, passed to tlsPHash
+ unsigned labelSeedLen;
+ unsigned char *tmpOut = NULL; // output of P_SHA1
+ unsigned i;
+ const unsigned char *secret = (const unsigned char *)vsecret;
+
+ /* two seeds for tlsPHash */
+ sLen = secretLen / 2; // for partitioning
+ S1 = secret;
+ S2 = &secret[sLen];
+ sLen += (secretLen & 1); // secret length odd, increment effective size
+
+ if(label != NULL) {
+ /* concatenate label and seed */
+ labelSeedLen = labelLen + seedLen;
+ labelSeed = (unsigned char *)sslMalloc(labelSeedLen);
+ if(labelSeed == NULL) {
+ return memFullErr;
+ }
+ memmove(labelSeed, label, labelLen);
+ memmove(labelSeed + labelLen, seed, seedLen);
+ }
+ else {
+ /* fast track - just use seed as is */
+ labelSeed = (unsigned char *)seed;
+ labelSeedLen = seedLen;
+ }
+
+ /* temporary output for SHA1, to be XORd with MD5 */
+ unsigned char *out = (unsigned char *)vout;
+ tmpOut = (unsigned char *)sslMalloc(outLen);
+ if(tmpOut == NULL) {
+ serr = memFullErr;
+ goto fail;
+ }
+ serr = tlsPHash(ctx, &TlsHmacMD5, S1, sLen, labelSeed, labelSeedLen,
+ out, outLen);
+ if(serr) {
+ goto fail;
+ }
+ serr = tlsPHash(ctx, &TlsHmacSHA1, S2, sLen, labelSeed, labelSeedLen,
+ tmpOut, outLen);
+ if(serr) {
+ goto fail;
+ }
+
+ /* XOR together to get final result */
+ for(i=0; i<outLen; i++) {
+ out[i] ^= tmpOut[i];
+ }
+ serr = noErr;
+
+fail:
+ if((labelSeed != NULL) && (label != NULL)) {
+ sslFree(labelSeed);
+ }
+ if(tmpOut != NULL) {
+ sslFree(tmpOut);
+ }
+ return serr;
+}
+
+/* not needed; encrypt/encode is the same for both protocols as long as
+ * we don't use the "variable length padding" feature. */
+#if 0
+static OSStatus tls1WriteRecord(
+ SSLRecord rec,
+ SSLContext *ctx)
+{
+ assert(0);
+ return unimpErr;
+}
+#endif
+
+static OSStatus tls1DecryptRecord(
+ UInt8 type,
+ SSLBuffer *payload,
+ SSLContext *ctx)
+{
+ OSStatus err;
+ SSLBuffer content;
+
+ if ((ctx->readCipher.symCipher->blockSize > 0) &&
+ ((payload->length % ctx->readCipher.symCipher->blockSize) != 0)) {
+ SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ return errSSLProtocol;
+ }
+
+ /* Decrypt in place */
+ if ((err = ctx->readCipher.symCipher->decrypt(*payload,
+ *payload,
+ &ctx->readCipher,
+ ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+ return err;
+ }
+
+ /* Locate content within decrypted payload */
+ content.data = payload->data;
+ content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
+ if (ctx->readCipher.symCipher->blockSize > 0) {
+ /* for TLSv1, padding can be anywhere from 0 to 255 bytes */
+ UInt8 padSize = payload->data[payload->length - 1];
+ UInt8 *padChars;
+
+ /* verify that all padding bytes are equal - WARNING - OpenSSL code
+ * has a special case here dealing with some kind of bug related to
+ * even size packets...beware... */
+ if(padSize > payload->length) {
+ SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ sslErrorLog("tls1DecryptRecord: bad padding length (%d)\n",
+ (unsigned)payload->data[payload->length - 1]);
+ return errSSLProtocol;
+ }
+ padChars = payload->data + payload->length - padSize;
+ while(padChars < (payload->data + payload->length)) {
+ if(*padChars++ != padSize) {
+ SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+ sslErrorLog("tls1DecryptRecord: bad padding value\n");
+ return errSSLProtocol;
+ }
+ }
+ /* Remove block size padding and its one-byte length */
+ content.length -= (1 + padSize);
+ }
+
+ /* Verify MAC on payload */
+ if (ctx->readCipher.macRef->hash->digestSize > 0)
+ /* Optimize away MAC for null case */
+ if ((err = SSLVerifyMac(type, content,
+ payload->data + content.length, ctx)) != 0)
+ { SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
+ return err;
+ }
+
+ *payload = content; /* Modify payload buffer to indicate content length */
+
+ return noErr;
+}
+
+/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
+static OSStatus tls1InitMac (
+ CipherContext *cipherCtx, // macRef, macSecret valid on entry
+ // macCtx valid on return
+ SSLContext *ctx)
+{
+ const HMACReference *hmac;
+ OSStatus serr;
+
+ assert(cipherCtx->macRef != NULL);
+ hmac = cipherCtx->macRef->hmac;
+ assert(hmac != NULL);
+
+ if(cipherCtx->macCtx.hmacCtx != NULL) {
+ hmac->free(cipherCtx->macCtx.hmacCtx);
+ cipherCtx->macCtx.hmacCtx = NULL;
+ }
+ serr = hmac->alloc(hmac, ctx, cipherCtx->macSecret,
+ cipherCtx->macRef->hmac->macSize, &cipherCtx->macCtx.hmacCtx);
+
+ /* mac secret now stored in macCtx.hmacCtx, delete it from cipherCtx */
+ memset(cipherCtx->macSecret, 0, sizeof(cipherCtx->macSecret));
+ return serr;
+}
+
+static OSStatus tls1FreeMac (
+ CipherContext *cipherCtx)
+{
+ /* this can be called on a completely zeroed out CipherContext... */
+ if(cipherCtx->macRef == NULL) {
+ return noErr;
+ }
+ assert(cipherCtx->macRef->hmac != NULL);
+
+ if(cipherCtx->macCtx.hmacCtx != NULL) {
+ cipherCtx->macRef->hmac->free(cipherCtx->macCtx.hmacCtx);
+ cipherCtx->macCtx.hmacCtx = NULL;
+ }
+ return noErr;
+}
+
+/*
+ * mac = HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
+ * TLSCompressed.version + TLSCompressed.length +
+ * TLSCompressed.fragment));
+ */
+
+/* sequence, type, version, length */
+#define HDR_LENGTH (8 + 1 + 2 + 2)
+OSStatus tls1ComputeMac (
+ UInt8 type,
+ SSLBuffer data,
+ SSLBuffer mac, // caller mallocs data
+ CipherContext *cipherCtx, // assumes macCtx, macRef
+ sslUint64 seqNo,
+ SSLContext *ctx)
+{
+ unsigned char hdr[HDR_LENGTH];
+ unsigned char *p;
+ HMACContextRef hmacCtx;
+ OSStatus serr;
+ const HMACReference *hmac;
+ unsigned macLength;
+
+ assert(cipherCtx != NULL);
+ assert(cipherCtx->macRef != NULL);
+ hmac = cipherCtx->macRef->hmac;
+ assert(hmac != NULL);
+ hmacCtx = cipherCtx->macCtx.hmacCtx; // may be NULL, for null cipher
+
+ serr = hmac->init(hmacCtx);
+ if(serr) {
+ goto fail;
+ }
+ p = SSLEncodeUInt64(hdr, seqNo);
+ *p++ = type;
+ *p++ = TLS_Version_1_0 >> 8;
+ *p++ = TLS_Version_1_0 & 0xff;
+ *p++ = data.length >> 8;
+ *p = data.length & 0xff;
+ serr = hmac->update(hmacCtx, hdr, HDR_LENGTH);
+ if(serr) {
+ goto fail;
+ }
+ serr = hmac->update(hmacCtx, data.data, data.length);
+ if(serr) {
+ goto fail;
+ }
+ macLength = mac.length;
+ serr = hmac->final(hmacCtx, mac.data, &macLength);
+ if(serr) {
+ goto fail;
+ }
+ mac.length = macLength;
+fail:
+ return serr;
+}
+
+/*
+ * On input, the following are valid:
+ * MasterSecret[48]
+ * ClientHello.random[32]
+ * ServerHello.random[32]
+ *
+ * key_block = PRF(SecurityParameters.master_secret,
+ * "key expansion",
+ * SecurityParameters.server_random +
+ * SecurityParameters.client_random);
+ */
+
+#define GKM_SEED_LEN (PLS_KEY_EXPAND_LEN + (2 * SSL_CLIENT_SRVR_RAND_SIZE))
+
+OSStatus tls1GenerateKeyMaterial (
+ SSLBuffer key, // caller mallocs and specifies length of
+ // required key material here
+ SSLContext *ctx)
+{
+ unsigned char seedBuf[GKM_SEED_LEN];
+ OSStatus serr;
+
+ /* use optimized label-less PRF */
+ memmove(seedBuf, PLS_KEY_EXPAND, PLS_KEY_EXPAND_LEN);
+ memmove(seedBuf + PLS_KEY_EXPAND_LEN, ctx->serverRandom,
+ SSL_CLIENT_SRVR_RAND_SIZE);
+ memmove(seedBuf + PLS_KEY_EXPAND_LEN + SSL_CLIENT_SRVR_RAND_SIZE,
+ ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
+ serr = SSLInternal_PRF(ctx,
+ ctx->masterSecret,
+ SSL_MASTER_SECRET_SIZE,
+ NULL, // no label
+ 0,
+ seedBuf,
+ GKM_SEED_LEN,
+ key.data, // destination
+ key.length);
+ tlsDump("key expansion", key.data, key.length);
+ return serr;
+}
+
+/*
+ * final_client_write_key =
+ * PRF(SecurityParameters.client_write_key,
+ * "client write key",
+ * SecurityParameters.client_random +
+ * SecurityParameters.server_random);
+ * final_server_write_key =
+ * PRF(SecurityParameters.server_write_key,
+ * "server write key",
+ * SecurityParameters.client_random +
+ * SecurityParameters.server_random);
+ *
+ * iv_block = PRF("", "IV block", SecurityParameters.client_random +
+ * SecurityParameters.server_random);
+ *
+ * iv_block is broken up into:
+ *
+ * client_write_IV[SecurityParameters.IV_size]
+ * server_write_IV[SecurityParameters.IV_size]
+ */
+OSStatus tls1GenerateExportKeyAndIv (
+ SSLContext *ctx, // clientRandom, serverRandom valid
+ const SSLBuffer clientWriteKey,
+ const SSLBuffer serverWriteKey,
+ SSLBuffer finalClientWriteKey, // RETURNED, mallocd by caller
+ SSLBuffer finalServerWriteKey, // RETURNED, mallocd by caller
+ SSLBuffer finalClientIV, // RETURNED, mallocd by caller
+ SSLBuffer finalServerIV) // RETURNED, mallocd by caller
+{
+ unsigned char randBuf[2 * SSL_CLIENT_SRVR_RAND_SIZE];
+ OSStatus serr;
+ unsigned char *ivBlock;
+ char *nullKey = "";
+
+ /* all three PRF calls use the same seed */
+ memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
+ memmove(randBuf + SSL_CLIENT_SRVR_RAND_SIZE,
+ ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
+
+ serr = SSLInternal_PRF(ctx,
+ clientWriteKey.data,
+ clientWriteKey.length,
+ (const unsigned char *)PLS_EXPORT_CLIENT_WRITE,
+ PLS_EXPORT_CLIENT_WRITE_LEN,
+ randBuf,
+ 2 * SSL_CLIENT_SRVR_RAND_SIZE,
+ finalClientWriteKey.data, // destination
+ finalClientWriteKey.length);
+ if(serr) {
+ return serr;
+ }
+ serr = SSLInternal_PRF(ctx,
+ serverWriteKey.data,
+ serverWriteKey.length,
+ (const unsigned char *)PLS_EXPORT_SERVER_WRITE,
+ PLS_EXPORT_SERVER_WRITE_LEN,
+ randBuf,
+ 2 * SSL_CLIENT_SRVR_RAND_SIZE,
+ finalServerWriteKey.data, // destination
+ finalServerWriteKey.length);
+ if(serr) {
+ return serr;
+ }
+ if((finalClientIV.length == 0) && (finalServerIV.length == 0)) {
+ /* skip remainder as optimization */
+ return noErr;
+ }
+ ivBlock = (unsigned char *)sslMalloc(finalClientIV.length + finalServerIV.length);
+ if(ivBlock == NULL) {
+ return memFullErr;
+ }
+ serr = SSLInternal_PRF(ctx,
+ (const unsigned char *)nullKey,
+ 0,
+ (const unsigned char *)PLS_EXPORT_IV_BLOCK,
+ PLS_EXPORT_IV_BLOCK_LEN,
+ randBuf,
+ 2 * SSL_CLIENT_SRVR_RAND_SIZE,
+ ivBlock, // destination
+ finalClientIV.length + finalServerIV.length);
+ if(serr) {
+ goto done;
+ }
+ memmove(finalClientIV.data, ivBlock, finalClientIV.length);
+ memmove(finalServerIV.data, ivBlock + finalClientIV.length, finalServerIV.length);
+done:
+ sslFree(ivBlock);
+ return serr;
+}
+
+/*
+ * On entry: clientRandom, serverRandom, preMasterSecret valid
+ * On return: masterSecret valid
+ *
+ * master_secret = PRF(pre_master_secret, "master secret",
+ * ClientHello.random + ServerHello.random)
+ * [0..47];
+ */
+
+OSStatus tls1GenerateMasterSecret (
+ SSLContext *ctx)
+{
+ unsigned char randBuf[2 * SSL_CLIENT_SRVR_RAND_SIZE];
+ OSStatus serr;
+
+ memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
+ memmove(randBuf + SSL_CLIENT_SRVR_RAND_SIZE,
+ ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
+ serr = SSLInternal_PRF(ctx,
+ ctx->preMasterSecret.data,
+ ctx->preMasterSecret.length,
+ (const unsigned char *)PLS_MASTER_SECRET,
+ PLS_MASTER_SECRET_LEN,
+ randBuf,
+ 2 * SSL_CLIENT_SRVR_RAND_SIZE,
+ ctx->masterSecret, // destination
+ SSL_MASTER_SECRET_SIZE);
+ tlsDump("master secret", ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
+ return serr;
+}
+
+/*
+ * Given digests contexts representing the running total of all handshake messages,
+ * calculate mac for "finished" message.
+ *
+ * verify_data = 12 bytes =
+ * PRF(master_secret, finished_label, MD5(handshake_messages) +
+ * SHA-1(handshake_messages)) [0..11];
+ */
+OSStatus tls1ComputeFinishedMac (
+ SSLContext *ctx,
+ SSLBuffer finished, // output - mallocd by caller
+ SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
+ SSLBuffer md5MsgState, // ditto
+ Boolean isServer)
+{
+ unsigned char digests[SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN];
+ SSLBuffer digBuf;
+ char *finLabel;
+ unsigned finLabelLen;
+ OSStatus serr;
+
+ if(isServer) {
+ finLabel = PLS_SERVER_FINISH;
+ finLabelLen = PLS_SERVER_FINISH_LEN;
+ }
+ else {
+ finLabel = PLS_CLIENT_FINISH;
+ finLabelLen = PLS_CLIENT_FINISH_LEN;
+ }
+
+ /* concatenate two digest results */
+ digBuf.data = digests;
+ digBuf.length = SSL_MD5_DIGEST_LEN;
+ serr = SSLHashMD5.final(md5MsgState, digBuf);
+ if(serr) {
+ return serr;
+ }
+ digBuf.data += SSL_MD5_DIGEST_LEN;
+ digBuf.length = SSL_SHA1_DIGEST_LEN;
+ serr = SSLHashSHA1.final(shaMsgState, digBuf);
+ if(serr) {
+ return serr;
+ }
+ return SSLInternal_PRF(ctx,
+ ctx->masterSecret,
+ SSL_MASTER_SECRET_SIZE,
+ (const unsigned char *)finLabel,
+ finLabelLen,
+ digests,
+ SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN,
+ finished.data, // destination
+ finished.length);
+}
+
+/*
+ * This one is trivial.
+ *
+ * mac := MD5(handshake_messages) + SHA(handshake_messages);
+ *
+ * I don't know why this one doesn't use an HMAC or the master secret (as SSLv3
+ * does).
+ */
+OSStatus tls1ComputeCertVfyMac (
+ SSLContext *ctx,
+ SSLBuffer finished, // output - mallocd by caller
+ SSLBuffer shaMsgState, // clone of running digest of all handshake msgs
+ SSLBuffer md5MsgState) // ditto
+{
+ SSLBuffer digBuf;
+ OSStatus serr;
+
+ assert(finished.length == (SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN));
+ digBuf.data = finished.data;
+ digBuf.length = SSL_MD5_DIGEST_LEN;
+ serr = SSLHashMD5.final(md5MsgState, digBuf);
+ if(serr) {
+ return serr;
+ }
+ digBuf.data = finished.data + SSL_MD5_DIGEST_LEN;
+ digBuf.length = SSL_SHA1_DIGEST_LEN;
+ return SSLHashSHA1.final(shaMsgState, digBuf);
+}
+
+const SslTlsCallouts Tls1Callouts = {
+ tls1DecryptRecord,
+ ssl3WriteRecord,
+ tls1InitMac,
+ tls1FreeMac,
+ tls1ComputeMac,
+ tls1GenerateKeyMaterial,
+ tls1GenerateExportKeyAndIv,
+ tls1GenerateMasterSecret,
+ tls1ComputeFinishedMac,
+ tls1ComputeCertVfyMac
+};
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This 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.
- */
-
-
-/*
- File: tls_hmac.c
-
- Contains: HMAC routines used by TLS
-
- Written by: Doug Mitchell
-*/
-
-#include "tls_hmac.h"
-#include "appleCdsa.h"
-#include "sslalloc.h"
-#include "sslerrs.h"
-#include "cryptType.h"
-#include "digests.h"
-#include <strings.h>
-#include <assert.h>
-#include <Security/cssm.h>
-
-/* Per-session state, opaque to callers; all fields set at alloc time */
-struct HMACContext {
- SSLContext *ctx;
- CSSM_CC_HANDLE ccHand;
- const struct HMACReference *hmac;
-};
-
-#pragma mark *** Common CDSA_based HMAC routines ***
-
-/* Create an HMAC session */
-static SSLErr HMAC_Alloc(
- const struct HMACReference *hmac,
- SSLContext *ctx,
- const void *keyPtr,
- unsigned keyLen,
- HMACContextRef *hmacCtx) // RETURNED
-{
- CSSM_RETURN crtn;
- CSSM_KEY cssmKey;
- SSLErr serr;
- CSSM_ALGORITHMS calg;
- HMACContextRef href = sslMalloc(sizeof(struct HMACContext));
-
- if(href == NULL) {
- return SSLMemoryErr;
- }
- href->ctx = ctx;
- href->ccHand = 0;
- href->hmac = hmac;
-
- /*
- * Since the key is present in the CDSA context, we cook up the context now.
- * Currently we can't reuse an HMAC context if the key changes.
- */
- switch(hmac->alg) {
- case HA_SHA1:
- calg = CSSM_ALGID_SHA1HMAC;
- break;
- case HA_MD5:
- calg = CSSM_ALGID_MD5HMAC;
- break;
- default:
- assert(0);
- return SSLInternalError;
- }
- serr = sslSetUpSymmKey(&cssmKey,
- calg,
- CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY,
- CSSM_FALSE, /* don't malloc/copy key */
- (uint8 *)keyPtr,
- keyLen);
- if(serr) {
- return serr;
- }
- if(attachToCsp(ctx)) {
- return serr;
- }
- crtn = CSSM_CSP_CreateMacContext(ctx->cspHand,
- calg,
- &cssmKey,
- &href->ccHand);
- if(crtn) {
- return SSLCryptoError;
- }
-
- /* success */
- *hmacCtx = href;
- return SSLNoErr;
-}
-
-/* free a session */
-static SSLErr HMAC_Free(
- HMACContextRef hmacCtx)
-{
- if(hmacCtx != NULL) {
- if(hmacCtx->ccHand != 0) {
- CSSM_DeleteContext(hmacCtx->ccHand);
- hmacCtx->ccHand = 0;
- }
- sslFree(hmacCtx);
- }
- return SSLNoErr;
-}
-
-/* Reusable init */
-static SSLErr HMAC_Init(
- HMACContextRef hmacCtx)
-{
- CSSM_RETURN crtn;
-
- if(hmacCtx == NULL) {
- return SSLInternalError;
- }
- assert(hmacCtx->ctx != NULL);
- assert(hmacCtx->hmac != NULL);
- assert(hmacCtx->ccHand != 0);
-
- crtn = CSSM_GenerateMacInit(hmacCtx->ccHand);
- if(crtn) {
- return SSLCryptoError;
- }
- return SSLNoErr;
-}
-
-/* normal crypt ops */
-static SSLErr HMAC_Update(
- HMACContextRef hmacCtx,
- const void *data,
- unsigned dataLen)
-{
- CSSM_RETURN crtn;
- CSSM_DATA cdata;
-
- if(hmacCtx == NULL) {
- return SSLInternalError;
- }
- assert(hmacCtx->ctx != NULL);
- assert(hmacCtx->hmac != NULL);
- assert(hmacCtx->ccHand != 0);
- cdata.Data = (uint8 *)data;
- cdata.Length = dataLen;
- crtn = CSSM_GenerateMacUpdate(hmacCtx->ccHand, &cdata, 1);
- if(crtn) {
- return SSLCryptoError;
- }
- return SSLNoErr;
-}
-
-static SSLErr HMAC_Final(
- HMACContextRef hmacCtx,
- void *hmac, // mallocd by caller
- unsigned *hmacLen) // IN/OUT
-{
- CSSM_RETURN crtn;
- CSSM_DATA cdata;
-
- if(hmacCtx == NULL) {
- return SSLInternalError;
- }
- if((hmac == NULL) || (hmacLen == 0)) {
- return SSLInternalError;
- }
- assert(hmacCtx->ctx != NULL);
- assert(hmacCtx->hmac != NULL);
- assert(hmacCtx->ccHand != 0);
- cdata.Data = (uint8 *)hmac;
- cdata.Length = *hmacLen;
- crtn = CSSM_GenerateMacFinal(hmacCtx->ccHand, &cdata);
- if(crtn) {
- return SSLCryptoError;
- }
- *hmacLen = cdata.Length;
- return SSLNoErr;
-}
-
-/* one-shot */
-static SSLErr HMAC_Hmac (
- HMACContextRef hmacCtx,
- const void *data,
- unsigned dataLen,
- void *hmac, // mallocd by caller
- unsigned *hmacLen) // IN/OUT
-{
- SSLErr serr;
- const HMACReference *hmacRef;
-
- if(hmacCtx == NULL) {
- return SSLInternalError;
- }
- hmacRef = hmacCtx->hmac;
- assert(hmacRef != NULL);
- serr = hmacRef->init(hmacCtx);
- if(serr) {
- return serr;
- }
- serr = hmacRef->update(hmacCtx, data, dataLen);
- if(serr) {
- return serr;
- }
- return hmacRef->final(hmacCtx, hmac, hmacLen);
-}
-
-#pragma mark *** Null HMAC ***
-
-static SSLErr HMAC_AllocNull(
- const struct HMACReference *hmac,
- SSLContext *ctx,
- const void *keyPtr,
- unsigned keyLen,
- HMACContextRef *hmacCtx) // RETURNED
-{
- *hmacCtx = NULL;
- return SSLNoErr;
-}
-
-static SSLErr HMAC_FreeNull(
- HMACContextRef hmacCtx)
-{
- return SSLNoErr;
-}
-
-static SSLErr HMAC_InitNull(
- HMACContextRef hmacCtx)
- {
- return SSLNoErr;
-}
-
-static SSLErr HMAC_UpdateNull(
- HMACContextRef hmacCtx,
- const void *data,
- unsigned dataLen)
-{
- return SSLNoErr;
-}
-
-static SSLErr HMAC_FinalNull(
- HMACContextRef hmacCtx,
- void *hmac, // mallocd by caller
- unsigned *hmacLen) // IN/OUT
-{
- return SSLNoErr;
-}
-
-static SSLErr HMAC_HmacNull (
- HMACContextRef hmacCtx,
- const void *data,
- unsigned dataLen,
- void *hmac, // mallocd by caller
- unsigned *hmacLen)
-{
- return SSLNoErr;
-}
-
-const HMACReference TlsHmacNull = {
- 0,
- HA_Null,
- HMAC_AllocNull,
- HMAC_FreeNull,
- HMAC_InitNull,
- HMAC_UpdateNull,
- HMAC_FinalNull,
- HMAC_HmacNull
-};
-
-const HMACReference TlsHmacSHA1 = {
- 20,
- HA_SHA1,
- HMAC_Alloc,
- HMAC_Free,
- HMAC_Init,
- HMAC_Update,
- HMAC_Final,
- HMAC_Hmac
-};
-
-const HMACReference TlsHmacMD5 = {
- 16,
- HA_MD5,
- HMAC_Alloc,
- HMAC_Free,
- HMAC_Init,
- HMAC_Update,
- HMAC_Final,
- HMAC_Hmac
-};
-
-const HashHmacReference HashHmacNull = {
- &SSLHashNull,
- &TlsHmacNull
-};
-
-const HashHmacReference HashHmacMD5 = {
- &SSLHashMD5,
- &TlsHmacMD5
-};
-
-const HashHmacReference HashHmacSHA1 = {
- &SSLHashSHA1,
- &TlsHmacSHA1
-};
--- /dev/null
+/*
+ * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This 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.
+ */
+
+
+/*
+ File: tls_hmac.c
+
+ Contains: HMAC routines used by TLS
+
+ Written by: Doug Mitchell
+*/
+
+#include "tls_hmac.h"
+#include "appleCdsa.h"
+#include "sslMemory.h"
+#include "cryptType.h"
+#include "sslDigests.h"
+#include <strings.h>
+#include <assert.h>
+#include <Security/cssm.h>
+
+/* Per-session state, opaque to callers; all fields set at alloc time */
+struct HMACContext {
+ SSLContext *ctx;
+ CSSM_CC_HANDLE ccHand;
+ const struct HMACReference *hmac;
+};
+
+#pragma mark *** Common CDSA_based HMAC routines ***
+
+/* Create an HMAC session */
+static OSStatus HMAC_Alloc(
+ const struct HMACReference *hmac,
+ SSLContext *ctx,
+ const void *keyPtr,
+ unsigned keyLen,
+ HMACContextRef *hmacCtx) // RETURNED
+{
+ CSSM_RETURN crtn;
+ CSSM_KEY cssmKey;
+ OSStatus serr;
+ CSSM_ALGORITHMS calg;
+ HMACContextRef href = (HMACContextRef)sslMalloc(sizeof(struct HMACContext));
+
+ if(href == NULL) {
+ return memFullErr;
+ }
+ href->ctx = ctx;
+ href->ccHand = 0;
+ href->hmac = hmac;
+
+ /*
+ * Since the key is present in the CDSA context, we cook up the context now.
+ * Currently we can't reuse an HMAC context if the key changes.
+ */
+ switch(hmac->alg) {
+ case HA_SHA1:
+ calg = CSSM_ALGID_SHA1HMAC;
+ break;
+ case HA_MD5:
+ calg = CSSM_ALGID_MD5HMAC;
+ break;
+ default:
+ assert(0);
+ return errSSLInternal;
+ }
+ serr = sslSetUpSymmKey(&cssmKey,
+ calg,
+ CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY,
+ CSSM_FALSE, /* don't malloc/copy key */
+ (uint8 *)keyPtr,
+ keyLen);
+ if(serr) {
+ return serr;
+ }
+ if(attachToCsp(ctx)) {
+ return serr;
+ }
+ crtn = CSSM_CSP_CreateMacContext(ctx->cspHand,
+ calg,
+ &cssmKey,
+ &href->ccHand);
+ if(crtn) {
+ return errSSLCrypto;
+ }
+
+ /* success */
+ *hmacCtx = href;
+ return noErr;
+}
+
+/* free a session */
+static OSStatus HMAC_Free(
+ HMACContextRef hmacCtx)
+{
+ if(hmacCtx != NULL) {
+ if(hmacCtx->ccHand != 0) {
+ CSSM_DeleteContext(hmacCtx->ccHand);
+ hmacCtx->ccHand = 0;
+ }
+ sslFree(hmacCtx);
+ }
+ return noErr;
+}
+
+/* Reusable init */
+static OSStatus HMAC_Init(
+ HMACContextRef hmacCtx)
+{
+ CSSM_RETURN crtn;
+
+ if(hmacCtx == NULL) {
+ return errSSLInternal;
+ }
+ assert(hmacCtx->ctx != NULL);
+ assert(hmacCtx->hmac != NULL);
+ assert(hmacCtx->ccHand != 0);
+
+ crtn = CSSM_GenerateMacInit(hmacCtx->ccHand);
+ if(crtn) {
+ return errSSLCrypto;
+ }
+ return noErr;
+}
+
+/* normal crypt ops */
+static OSStatus HMAC_Update(
+ HMACContextRef hmacCtx,
+ const void *data,
+ unsigned dataLen)
+{
+ CSSM_RETURN crtn;
+ CSSM_DATA cdata;
+
+ if(hmacCtx == NULL) {
+ return errSSLInternal;
+ }
+ assert(hmacCtx->ctx != NULL);
+ assert(hmacCtx->hmac != NULL);
+ assert(hmacCtx->ccHand != 0);
+ cdata.Data = (uint8 *)data;
+ cdata.Length = dataLen;
+ crtn = CSSM_GenerateMacUpdate(hmacCtx->ccHand, &cdata, 1);
+ if(crtn) {
+ return errSSLCrypto;
+ }
+ return noErr;
+}
+
+static OSStatus HMAC_Final(
+ HMACContextRef hmacCtx,
+ void *hmac, // mallocd by caller
+ unsigned *hmacLen) // IN/OUT
+{
+ CSSM_RETURN crtn;
+ CSSM_DATA cdata;
+
+ if(hmacCtx == NULL) {
+ return errSSLInternal;
+ }
+ if((hmac == NULL) || (hmacLen == 0)) {
+ return errSSLInternal;
+ }
+ assert(hmacCtx->ctx != NULL);
+ assert(hmacCtx->hmac != NULL);
+ assert(hmacCtx->ccHand != 0);
+ cdata.Data = (uint8 *)hmac;
+ cdata.Length = *hmacLen;
+ crtn = CSSM_GenerateMacFinal(hmacCtx->ccHand, &cdata);
+ if(crtn) {
+ return errSSLCrypto;
+ }
+ *hmacLen = cdata.Length;
+ return noErr;
+}
+
+/* one-shot */
+static OSStatus HMAC_Hmac (
+ HMACContextRef hmacCtx,
+ const void *data,
+ unsigned dataLen,
+ void *hmac, // mallocd by caller
+ unsigned *hmacLen) // IN/OUT
+{
+ OSStatus serr;
+ const HMACReference *hmacRef;
+
+ if(hmacCtx == NULL) {
+ return errSSLInternal;
+ }
+ hmacRef = hmacCtx->hmac;
+ assert(hmacRef != NULL);
+ serr = hmacRef->init(hmacCtx);
+ if(serr) {
+ return serr;
+ }
+ serr = hmacRef->update(hmacCtx, data, dataLen);
+ if(serr) {
+ return serr;
+ }
+ return hmacRef->final(hmacCtx, hmac, hmacLen);
+}
+
+#pragma mark *** Null HMAC ***
+
+static OSStatus HMAC_AllocNull(
+ const struct HMACReference *hmac,
+ SSLContext *ctx,
+ const void *keyPtr,
+ unsigned keyLen,
+ HMACContextRef *hmacCtx) // RETURNED
+{
+ *hmacCtx = NULL;
+ return noErr;
+}
+
+static OSStatus HMAC_FreeNull(
+ HMACContextRef hmacCtx)
+{
+ return noErr;
+}
+
+static OSStatus HMAC_InitNull(
+ HMACContextRef hmacCtx)
+ {
+ return noErr;
+}
+
+static OSStatus HMAC_UpdateNull(
+ HMACContextRef hmacCtx,
+ const void *data,
+ unsigned dataLen)
+{
+ return noErr;
+}
+
+static OSStatus HMAC_FinalNull(
+ HMACContextRef hmacCtx,
+ void *hmac, // mallocd by caller
+ unsigned *hmacLen) // IN/OUT
+{
+ return noErr;
+}
+
+static OSStatus HMAC_HmacNull (
+ HMACContextRef hmacCtx,
+ const void *data,
+ unsigned dataLen,
+ void *hmac, // mallocd by caller
+ unsigned *hmacLen)
+{
+ return noErr;
+}
+
+const HMACReference TlsHmacNull = {
+ 0,
+ HA_Null,
+ HMAC_AllocNull,
+ HMAC_FreeNull,
+ HMAC_InitNull,
+ HMAC_UpdateNull,
+ HMAC_FinalNull,
+ HMAC_HmacNull
+};
+
+const HMACReference TlsHmacSHA1 = {
+ 20,
+ HA_SHA1,
+ HMAC_Alloc,
+ HMAC_Free,
+ HMAC_Init,
+ HMAC_Update,
+ HMAC_Final,
+ HMAC_Hmac
+};
+
+const HMACReference TlsHmacMD5 = {
+ 16,
+ HA_MD5,
+ HMAC_Alloc,
+ HMAC_Free,
+ HMAC_Init,
+ HMAC_Update,
+ HMAC_Final,
+ HMAC_Hmac
+};
+
+const HashHmacReference HashHmacNull = {
+ &SSLHashNull,
+ &TlsHmacNull
+};
+
+const HashHmacReference HashHmacMD5 = {
+ &SSLHashMD5,
+ &TlsHmacMD5
+};
+
+const HashHmacReference HashHmacSHA1 = {
+ &SSLHashSHA1,
+ &TlsHmacSHA1
+};
_SSLGetEnabledCiphers
_SSLSetAllowsExpiredCerts
_SSLGetAllowsExpiredCerts
+_SSLSetAllowsExpiredRoots
+_SSLGetAllowsExpiredRoots
+_SSLSetEnableCertVerify
+_SSLGetEnableCertVerify
_SSLGetPeerCertificates
+_SSLSetTrustedRoots
+_SSLGetTrustedRoots
_SSLSetPeerID
_SSLGetPeerID
_SSLSetPeerDomainName
_SSLClose
_SSLSetAllowsAnyRoot
_SSLGetAllowsAnyRoot
+_SSLAddDistinguishedName
+_SSLSetClientSideAuthenticate
_SessionGetInfo
_SessionCreate
_checkpw
_checkpw_internal
+_SSLInternalMasterSecret
+_SSLInternalServerRandom
+_SSLInternalClientRandom
+_SSLInternal_PRF
+_SSLGetClientCertificateState
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/BSafe.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/BSafe.framework/Headers\" \"$(SRCROOT)/AppleCSP\" \"$(SRCROOT)/AppleCSP/open_ssl\"";
LIBRARY_STYLE = STATIC;
9D291891026B8BBD00003D05,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880D0005EAE4D11CD283A = {
buildActionMask = 2147483647;
9D291890026B8BBD00003D05,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880D1005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880D2005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880D4005EAE4D11CD283A = {
buildPhases = (
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "-DVDADER_RULES";
0148812E005EB04411CD283A,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880D6005EAE4D11CD283A = {
buildActionMask = 2147483647;
327DDDF500D707D805CD296C,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880D7005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880D8005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880DA005EAE4D11CD283A = {
buildPhases = (
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
01488139005EB04411CD283A,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880DC005EAE4D11CD283A = {
buildActionMask = 2147483647;
0148813A005EB04411CD283A,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880DD005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880DE005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880E0005EAE4D11CD283A = {
buildPhases = (
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "-DVDADER_RULES";
01488144005EB04411CD283A,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880E2005EAE4D11CD283A = {
buildActionMask = 2147483647;
F540EDC3027A41BF01CA2E66,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880E3005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880E4005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880E6005EAE4D11CD283A = {
buildPhases = (
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "-DVDADER_RULES";
01488159005EB04411CD283A,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880E8005EAE4D11CD283A = {
buildActionMask = 2147483647;
9D9AEFBB02B6BC6C00003D05,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880E9005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880EA005EAE4D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
014880EC005EB04411CD283A = {
fileRef = 07A0F5EE005DAEE111CD283A;
01FA8126FFF2B54C11CD283A = {
children = (
01FA8127FFF2B54C11CD283A,
- 01FA8128FFF2B54C11CD283A,
01FA8129FFF2B54C11CD283A,
01FA812AFFF2B54C11CD283A,
- 01FA812BFFF2B54C11CD283A,
01FA812CFFF2B54C11CD283A,
01FA812DFFF2B54C11CD283A,
01FA812EFFF2B54C11CD283A,
01FA812FFFF2B54C11CD283A,
01FA8130FFF2B54C11CD283A,
01FA8131FFF2B54C11CD283A,
- 01FA8132FFF2B54C11CD283A,
- 01FA8133FFF2B54C11CD283A,
01FA8135FFF2B54C11CD283A,
01FA8136FFF2B54C11CD283A,
01FA8137FFF2B54C11CD283A,
};
01FA8127FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = appleCdsa.c;
- refType = 4;
- };
- 01FA8128FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = appleGlue.c;
+ path = appleCdsa.cpp;
refType = 4;
};
01FA8129FFF2B54C11CD283A = {
};
01FA812AFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = cipherSpecs.c;
- refType = 4;
- };
- 01FA812BFFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = cppUtils.cpp;
+ path = cipherSpecs.cpp;
refType = 4;
};
01FA812CFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = digests.c;
+ path = sslDigests.cpp;
refType = 4;
};
01FA812DFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = hdskcert.c;
+ path = sslCert.cpp;
refType = 4;
};
01FA812EFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = hdskchgc.c;
+ path = sslChangeCipher.cpp;
refType = 4;
};
01FA812FFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = hdskfini.c;
+ path = sslHandshakeFinish.cpp;
refType = 4;
};
01FA8130FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = hdskhelo.c;
+ path = sslHandshakeHello.cpp;
refType = 4;
};
01FA8131FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = hdskkeys.c;
- refType = 4;
- };
- 01FA8132FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = hdskkyex.c;
- refType = 4;
- };
- 01FA8133FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = LICENSE.txt;
+ path = sslKeyExchange.cpp;
refType = 4;
};
01FA8135FFF2B54C11CD283A = {
};
01FA8137FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = nullciph.c;
+ path = sslNullCipher.cpp;
refType = 4;
};
01FA8138FFF2B54C11CD283A = {
children = (
01FA8139FFF2B54C11CD283A,
- 01FA813AFFF2B54C11CD283A,
01FA813BFFF2B54C11CD283A,
01FA813CFFF2B54C11CD283A,
01FA813DFFF2B54C11CD283A,
- 01FA813EFFF2B54C11CD283A,
01FA8141FFF2B54C11CD283A,
01FA8142FFF2B54C11CD283A,
- 01FA8143FFF2B54C11CD283A,
- 01FA8144FFF2B54C11CD283A,
01FA8145FFF2B54C11CD283A,
01FA8146FFF2B54C11CD283A,
- 01FA8147FFF2B54C11CD283A,
01FA8148FFF2B54C11CD283A,
- 01FA8149FFF2B54C11CD283A,
- 01FA814AFFF2B54C11CD283A,
01FA814BFFF2B54C11CD283A,
01FA814CFFF2B54C11CD283A,
- 01FA814DFFF2B54C11CD283A,
- 01FA814EFFF2B54C11CD283A,
- 01FA814FFFF2B54C11CD283A,
- 01FA8150FFF2B54C11CD283A,
01FA8151FFF2B54C11CD283A,
9D78BC7201EBB3F900003D05,
9D78BC7601EBBBED00003D05,
+ 9D98FF0C0371DDE400003D05,
+ 9D98FF0D0371DDE400003D05,
+ 9D98FF0E0371DDE400003D05,
+ 9D98FF0F0371DDE400003D05,
+ 9D98FF100371DDE400003D05,
+ 9D98FF110371DDE400003D05,
+ 9D98FF120371DDE400003D05,
+ 9D98FF130371DDE400003D05,
+ 9D98FF140371DDE400003D05,
);
isa = PBXGroup;
path = privateInc;
path = appleCdsa.h;
refType = 4;
};
- 01FA813AFFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = appleGlue.h;
- refType = 4;
- };
01FA813BFFF2B54C11CD283A = {
isa = PBXFileReference;
path = appleSession.h;
path = cryptType.h;
refType = 4;
};
- 01FA813EFFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = digests.h;
- refType = 4;
- };
01FA8141FFF2B54C11CD283A = {
isa = PBXFileReference;
path = ssl.h;
path = ssl2.h;
refType = 4;
};
- 01FA8143FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslalert.h;
- refType = 4;
- };
- 01FA8144FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslalloc.h;
- refType = 4;
- };
01FA8145FFF2B54C11CD283A = {
isa = PBXFileReference;
path = sslBER.h;
path = sslBuildFlags.h;
refType = 4;
};
- 01FA8147FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslctx.h;
- refType = 4;
- };
01FA8148FFF2B54C11CD283A = {
isa = PBXFileReference;
path = sslDebug.h;
refType = 4;
};
- 01FA8149FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslerrs.h;
- refType = 4;
- };
- 01FA814AFFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslhdshk.h;
- refType = 4;
- };
01FA814BFFF2B54C11CD283A = {
isa = PBXFileReference;
path = sslKeychain.h;
path = sslPriv.h;
refType = 4;
};
- 01FA814DFFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslrec.h;
- refType = 4;
- };
- 01FA814EFFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslsess.h;
- refType = 4;
- };
- 01FA814FFFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = ssltrspt.h;
- refType = 4;
- };
- 01FA8150FFF2B54C11CD283A = {
- isa = PBXFileReference;
- path = sslutil.h;
- refType = 4;
- };
01FA8151FFF2B54C11CD283A = {
isa = PBXFileReference;
path = symCipher.h;
};
01FA8158FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = ssl2map.c;
+ path = ssl2CipherMap.cpp;
refType = 4;
};
01FA8159FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = ssl2mesg.c;
+ path = ssl2Message.cpp;
refType = 4;
};
01FA815AFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = ssl2prot.c;
+ path = ssl2Protocol.cpp;
refType = 4;
};
01FA815BFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = ssl2rec.c;
+ path = ssl2Record.cpp;
refType = 4;
};
01FA815CFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslalert.c;
+ path = sslAlertMessage.cpp;
refType = 4;
};
01FA815DFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslalloc.c;
+ path = sslMemory.cpp;
refType = 4;
};
01FA815EFFF2B54C11CD283A = {
};
01FA815FFFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslctx.c;
+ path = sslContext.cpp;
refType = 4;
};
01FA8161FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslhdshk.c;
+ path = sslHandshake.cpp;
refType = 4;
};
01FA8162FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslKeychain.c;
+ path = sslKeychain.cpp;
refType = 4;
};
01FA8163FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslrec.c;
+ path = sslRecord.cpp;
refType = 4;
};
01FA8164FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslsess.c;
+ path = sslSession.cpp;
refType = 4;
};
01FA8165FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = ssltrspt.c;
+ path = sslTransport.cpp;
refType = 4;
};
01FA8166FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = sslutil.c;
+ path = sslUtils.cpp;
refType = 4;
};
01FA8167FFF2B54C11CD283A = {
isa = PBXFileReference;
- path = symCipher.c;
+ path = symCipher.cpp;
refType = 4;
};
01FA8168FFF2B54C11CD283A = {
settings = {
};
};
- 01FA8519FFF2B54C11CD283A = {
- fileRef = 01FA813AFFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
01FA851AFFF2B54C11CD283A = {
fileRef = 01FA813BFFF2B54C11CD283A;
isa = PBXBuildFile;
settings = {
};
};
- 01FA851DFFF2B54C11CD283A = {
- fileRef = 01FA813EFFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
01FA8520FFF2B54C11CD283A = {
fileRef = 01FA8141FFF2B54C11CD283A;
isa = PBXBuildFile;
settings = {
};
};
- 01FA8522FFF2B54C11CD283A = {
- fileRef = 01FA8143FFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
- 01FA8523FFF2B54C11CD283A = {
- fileRef = 01FA8144FFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
01FA8524FFF2B54C11CD283A = {
fileRef = 01FA8145FFF2B54C11CD283A;
isa = PBXBuildFile;
settings = {
};
};
- 01FA8526FFF2B54C11CD283A = {
- fileRef = 01FA8147FFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
01FA8527FFF2B54C11CD283A = {
fileRef = 01FA8148FFF2B54C11CD283A;
isa = PBXBuildFile;
settings = {
};
};
- 01FA8528FFF2B54C11CD283A = {
- fileRef = 01FA8149FFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
- 01FA8529FFF2B54C11CD283A = {
- fileRef = 01FA814AFFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
01FA852AFFF2B54C11CD283A = {
fileRef = 01FA814BFFF2B54C11CD283A;
isa = PBXBuildFile;
settings = {
};
};
- 01FA852CFFF2B54C11CD283A = {
- fileRef = 01FA814DFFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
- 01FA852DFFF2B54C11CD283A = {
- fileRef = 01FA814EFFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
- 01FA852EFFF2B54C11CD283A = {
- fileRef = 01FA814FFFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
- 01FA852FFFF2B54C11CD283A = {
- fileRef = 01FA8150FFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- };
- };
01FA8530FFF2B54C11CD283A = {
fileRef = 01FA8151FFF2B54C11CD283A;
isa = PBXBuildFile;
);
};
};
- 01FA8750FFF2B54C11CD283A = {
- fileRef = 01FA8128FFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- );
- };
- };
01FA8751FFF2B54C11CD283A = {
fileRef = 01FA8129FFF2B54C11CD283A;
isa = PBXBuildFile;
);
};
};
- 01FA8753FFF2B54C11CD283A = {
- fileRef = 01FA812BFFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- );
- };
- };
01FA8754FFF2B54C11CD283A = {
fileRef = 01FA812CFFF2B54C11CD283A;
isa = PBXBuildFile;
);
};
};
- 01FA875AFFF2B54C11CD283A = {
- fileRef = 01FA8132FFF2B54C11CD283A;
- isa = PBXBuildFile;
- settings = {
- ATTRIBUTES = (
- );
- };
- };
01FA875CFFF2B54C11CD283A = {
fileRef = 01FA8135FFF2B54C11CD283A;
isa = PBXBuildFile;
01FA8900FFF2BC5611CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
PRODUCT_NAME = SecurityServer;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(SRCROOT)/SecurityServer/SecurityServer.order\" -e start";
- VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
};
dependencies = (
F5A7F720023D974F01CA2E64,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA88FEFFF2BC5611CD283A = {
buildActionMask = 2147483647;
F5A7F71F023D974E01CA2E64,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA88FFFFF2BC5611CD283A = {
buildActionMask = 2147483647;
3949557400CC6A4511CD283A,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA8900FFF2BC5611CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA8901FFF2BCA811CD283A = {
isa = PBXExecutableFileReference;
01FA890AFFF2BCA811CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
PRODUCT_NAME = AuthorizationTrampoline;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
- VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
};
dependencies = (
files = (
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA8906FFF2BCA811CD283A = {
buildActionMask = 2147483647;
01FA8907FFF2BCA811CD283A,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA8907FFF2BCA811CD283A = {
fileRef = 01FA81ACFFF2B54C11CD283A;
1BA451B30097605B7F000001,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA890AFFF2BCA811CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
01FA890DFFF2BD9911CD283A = {
children = (
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
files = (
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
030701E6FFF96F8511CD283A = {
buildActionMask = 2147483647;
030701EAFFF96F9911CD283A,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
030701E7FFF96F8511CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
030701E8FFF96F8511CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
030701E9FFF96F9911CD283A = {
fileRef = 01FA821CFFF2B54C11CD283A;
F5DDE3AE00B3358F01CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
FRAMEWORK_SEARCH_PATHS = "";
FRAMEWORK_VERSION = A;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(BUILT_PRODUCTS_DIR)/derived_src\"";
PREBINDING = YES;
PRODUCT_NAME = Security;
SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/Security.order\" -seg_addr_table \"$(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table\"";
- VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = Sec;
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = framework;
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>1.1.1</string>
+ <string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>54.1</string>
+ <string>54.1.3</string>
</dict>
</plist>
";
01FA84FFFFF2B54C11CD283A,
01FA8517FFF2B54C11CD283A,
01FA8518FFF2B54C11CD283A,
- 01FA8519FFF2B54C11CD283A,
01FA851AFFF2B54C11CD283A,
01FA851BFFF2B54C11CD283A,
01FA851CFFF2B54C11CD283A,
- 01FA851DFFF2B54C11CD283A,
01FA8520FFF2B54C11CD283A,
01FA8521FFF2B54C11CD283A,
- 01FA8522FFF2B54C11CD283A,
- 01FA8523FFF2B54C11CD283A,
01FA8524FFF2B54C11CD283A,
01FA8525FFF2B54C11CD283A,
- 01FA8526FFF2B54C11CD283A,
01FA8527FFF2B54C11CD283A,
- 01FA8528FFF2B54C11CD283A,
- 01FA8529FFF2B54C11CD283A,
01FA852AFFF2B54C11CD283A,
01FA852BFFF2B54C11CD283A,
- 01FA852CFFF2B54C11CD283A,
- 01FA852DFFF2B54C11CD283A,
- 01FA852EFFF2B54C11CD283A,
- 01FA852FFFF2B54C11CD283A,
01FA8530FFF2B54C11CD283A,
01FA8531FFF2B54C11CD283A,
01FA8532FFF2B54C11CD283A,
F5394A1C0279082901CA2E64,
F540EDC8027A43A501CA2E66,
3206D1FE029996FC05CA2E77,
+ 9D98FF150371DDE400003D05,
+ 9D98FF160371DDE400003D05,
+ 9D98FF170371DDE400003D05,
+ 9D98FF180371DDE400003D05,
+ 9D98FF190371DDE400003D05,
+ 9D98FF1A0371DDE400003D05,
+ 9D98FF1B0371DDE400003D05,
+ 9D98FF1C0371DDE400003D05,
+ 9D98FF1D0371DDE400003D05,
+ F500ED3C037CD0E101CA2E64,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
0867D69EFE84028FC02AAC07 = {
buildActionMask = 2147483647;
9DA13D0501B4638200003D05,
);
isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
0867D69FFE84028FC02AAC07 = {
buildActionMask = 2147483647;
01FA872FFFF2B54C11CD283A,
01FA8730FFF2B54C11CD283A,
01FA874FFFF2B54C11CD283A,
- 01FA8750FFF2B54C11CD283A,
01FA8751FFF2B54C11CD283A,
01FA8752FFF2B54C11CD283A,
- 01FA8753FFF2B54C11CD283A,
01FA8754FFF2B54C11CD283A,
01FA8755FFF2B54C11CD283A,
01FA8756FFF2B54C11CD283A,
01FA8757FFF2B54C11CD283A,
01FA8758FFF2B54C11CD283A,
01FA8759FFF2B54C11CD283A,
- 01FA875AFFF2B54C11CD283A,
01FA875CFFF2B54C11CD283A,
01FA875DFFF2B54C11CD283A,
01FA8760FFF2B54C11CD283A,
3206D1FD029996FC05CA2E77,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
0867D6A0FE84028FC02AAC07 = {
buildActionMask = 2147483647;
327DDDFB00D7E81F05CD296C,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
0867D6A2FE84028FC02AAC07 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
//080
//081
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 54.1;
+ DYLIB_CURRENT_VERSION = 54.1.3;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/include\"";
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
125E8606FFF3DB3E11CD283A,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
125E85D7FFF3D67D11CD283A = {
buildActionMask = 2147483647;
125E85D8FFF3D67D11CD283A,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
125E85D8FFF3D67D11CD283A = {
fileRef = 01FA8917FFF2BE3511CD283A;
files = (
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
125E85DAFFF3D67D11CD283A = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
125E85DCFFF3D76D11CD283A = {
isa = PBXTargetDependency;
325EAA2800D6B08805CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = AppleCSP;
SECTORDER_FLAGS = "";
- VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = bundle;
};
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>1.1.1</string>
+ <string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>54.1</string>
+ <string>54.1.3</string>
</dict>
</plist>
";
files = (
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
325EAA2500D6B08805CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
325EAA2600D6B08805CD296C = {
buildActionMask = 2147483647;
325EAA3800D6B47505CD296C,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
325EAA2700D6B08805CD296C = {
buildActionMask = 2147483647;
3290381400D6B78A05CD296C,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
325EAA2800D6B08805CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
325EAA2900D6B23F05CD296C = {
children = (
3290382100D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = AppleDL;
SECTORDER_FLAGS = "";
- VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = bundle;
};
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>1.1.1</string>
+ <string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>54.1</string>
+ <string>54.1.3</string>
</dict>
</plist>
";
files = (
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290381B00D6BA5905CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290381C00D6BA5905CD296C = {
buildActionMask = 2147483647;
3290383C00D6BB3705CD296C,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290381D00D6BA5905CD296C = {
buildActionMask = 2147483647;
3290382000D6BA5905CD296C,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290381E00D6BA5905CD296C = {
fileRef = 1BA451B10097605B7F000001;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382200D6BA5905CD296C = {
buildPhases = (
3290382700D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = AppleCSPDL;
SECTORDER_FLAGS = "";
- VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = bundle;
};
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>1.1.1</string>
+ <string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>54.1</string>
+ <string>54.1.3</string>
</dict>
</plist>
";
files = (
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382400D6BA5905CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382500D6BA5905CD296C = {
buildActionMask = 2147483647;
327DDDE800D6FC1B05CD296C,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382600D6BA5905CD296C = {
buildActionMask = 2147483647;
3290384100D6BB3705CD296C,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382700D6BA5905CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382800D6BA5905CD296C = {
buildPhases = (
3290382D00D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = AppleX509CL;
SECTORDER_FLAGS = "";
- VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = bundle;
};
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>1.1.1</string>
+ <string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>54.1</string>
+ <string>54.1.3</string>
</dict>
</plist>
";
files = (
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382A00D6BA5905CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382B00D6BA5905CD296C = {
buildActionMask = 2147483647;
3290384500D6BB3705CD296C,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382C00D6BA5905CD296C = {
buildActionMask = 2147483647;
3290384700D6BB3705CD296C,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382D00D6BA5905CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290382E00D6BA5905CD296C = {
buildPhases = (
3290383300D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 54.1;
+ CURRENT_PROJECT_VERSION = 54.1.3;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_LDFLAGS = "-bundle -undefined error";
OTHER_REZFLAGS = "";
PRODUCT_NAME = AppleX509TP;
SECTORDER_FLAGS = "";
- VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = bundle;
};
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>1.1.1</string>
+ <string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>54.1</string>
+ <string>54.1.3</string>
</dict>
</plist>
";
files = (
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290383000D6BA5905CD296C = {
buildActionMask = 2147483647;
9D103FA001AC72C200003D05,
);
isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290383100D6BA5905CD296C = {
buildActionMask = 2147483647;
3290384B00D6BB3705CD296C,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290383200D6BA5905CD296C = {
buildActionMask = 2147483647;
3290384D00D6BB3705CD296C,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290383300D6BA5905CD296C = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
3290383500D6BB3705CD296C = {
isa = PBXFileReference;
};
9D78BC7401EBB71A00003D05 = {
isa = PBXFileReference;
- path = tls_hmac.c;
+ path = tls_hmac.cpp;
refType = 4;
};
9D78BC7501EBB71A00003D05 = {
};
9D78BC7801EBCA2300003D05 = {
isa = PBXFileReference;
- path = ssl3Callouts.c;
+ path = ssl3Callouts.cpp;
refType = 4;
};
9D78BC7901EBCA2400003D05 = {
};
9D78BC7A01ECA79D00003D05 = {
isa = PBXFileReference;
- path = tls1Callouts.c;
+ path = tls1Callouts.cpp;
refType = 4;
};
9D78BC7B01ECA79D00003D05 = {
settings = {
};
};
+ 9D98FF0C0371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = SecureTransportPriv.h;
+ refType = 4;
+ };
+ 9D98FF0D0371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslAlertMessage.h;
+ refType = 4;
+ };
+ 9D98FF0E0371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslContext.h;
+ refType = 4;
+ };
+ 9D98FF0F0371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslDigests.h;
+ refType = 4;
+ };
+ 9D98FF100371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslHandshake.h;
+ refType = 4;
+ };
+ 9D98FF110371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslMemory.h;
+ refType = 4;
+ };
+ 9D98FF120371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslRecord.h;
+ refType = 4;
+ };
+ 9D98FF130371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslSession.h;
+ refType = 4;
+ };
+ 9D98FF140371DDE400003D05 = {
+ isa = PBXFileReference;
+ path = sslUtils.h;
+ refType = 4;
+ };
+ 9D98FF150371DDE400003D05 = {
+ fileRef = 9D98FF0C0371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Private,
+ );
+ };
+ };
+ 9D98FF160371DDE400003D05 = {
+ fileRef = 9D98FF0D0371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 9D98FF170371DDE400003D05 = {
+ fileRef = 9D98FF0E0371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 9D98FF180371DDE400003D05 = {
+ fileRef = 9D98FF0F0371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 9D98FF190371DDE400003D05 = {
+ fileRef = 9D98FF100371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 9D98FF1A0371DDE400003D05 = {
+ fileRef = 9D98FF110371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 9D98FF1B0371DDE400003D05 = {
+ fileRef = 9D98FF120371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 9D98FF1C0371DDE400003D05 = {
+ fileRef = 9D98FF130371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 9D98FF1D0371DDE400003D05 = {
+ fileRef = 9D98FF140371DDE400003D05;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
9D9AEFBA02B6BC6C00003D05 = {
isa = PBXFileReference;
path = rootCerts.cpp;
9DC1DF1B0299BDEB00003D05,
);
isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
9DC1DEF00299BBCD00003D05 = {
buildActionMask = 2147483647;
9DC1DF1A0299BDEA00003D05,
);
isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
9DC1DEF10299BBCD00003D05 = {
buildActionMask = 2147483647;
9DC1DF110299BD8C00003D05,
);
isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
9DC1DEF20299BBCD00003D05 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
};
9DC1DEF30299BBCD00003D05 = {
buildPhases = (
//F52
//F53
//F54
+ F500ED3B037CD0E101CA2E64 = {
+ isa = PBXFileReference;
+ path = SecKeyPriv.h;
+ refType = 4;
+ };
+ F500ED3C037CD0E101CA2E64 = {
+ fileRef = F500ED3B037CD0E101CA2E64;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Private,
+ );
+ };
+ };
F5394A1C0279082901CA2E64 = {
fileRef = 07A0F691005DAEE111CD283A;
isa = PBXBuildFile;
F578617B022EDE3F01CA2E64,
F57861C3022EEF3401CA2E64,
F57861C9022F0D0A01CA2E64,
+ F500ED3B037CD0E101CA2E64,
F5786173022EDDFB01CA2E64,
F5786175022EDE0501CA2E64,
F5786177022EDE1701CA2E64,
isa = PBXShellScriptBuildPhase;
neededFileNames = (
);
+ runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "${SRCROOT}/symbol_strip.sh ${SRCROOT}/Security.exp";
};
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:59 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: SecurityASN1
ProjectVersion: 6
--
-- MS 92
--
--- $Header: /cvs/Darwin/Security/SecurityASN1/asn/asn-useful.asn1,v 1.1.1.1 2001/05/18 23:13:59 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecurityASN1/asn/asn-useful.asn1,v 1.1.1.1 2001/05/18 23:13:59 mb Exp $
-- $Log: asn-useful.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:13:59 mb
-- Move from private repository to open source repository
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: SecuritySNACCRuntime
ProjectVersion: 6.1
i486/Linux, Alpha OSF/1 and many other machines.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/README,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/README,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:04 mb
# Move from private repository to open source repository
/*
* file: acconfig.h
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/acconfig.h,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/acconfig.h,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
* $Log: acconfig.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:04 mb
* Move from private repository to open source repository
--
-- this file is used in ../c{,++}-examples/any/
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/any.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/any.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: any.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
--
-- MS 92
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/asn-useful.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/asn-useful.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: asn-useful.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
-- Mike Sample 91/08/29
-- Modifed 92/05 MS
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/asn1module.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/asn1module.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: asn1module.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
--
-- Mike Sample 92/07
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/err-test.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/err-test.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: err-test.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
--
-- MS 92
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/ex1.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/ex1.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: ex1.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
--
-- this file is used in ../c{,++}-examples/simple/
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/p-rec.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/p-rec.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: p-rec.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
--
-- this file is used in ../c{,++}-examples/snmp/
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/rfc1155-smi.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/rfc1155-smi.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: rfc1155-smi.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
--
-- this file is used in ../c{,++}-examples/snmp/
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/rfc1157-snmp.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/rfc1157-snmp.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: rfc1157-snmp.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
--
-- this file is used in ../c{,++}-examples/snmp/
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/rfc1213-mib2.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/rfc1213-mib2.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: rfc1213-mib2.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
-- Mike Sample, April 11, 1992
-- Mods MS Feb 7/93
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/tbl.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/asn1specs/tbl.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
-- $Log: tbl.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:05 mb
-- Move from private repository to open source repository
explicitly initialized.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/any/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
// AUTHOR: Mike Sample
// DATE: 92
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/example.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/any/example.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
// $Log: example.C,v $
// Revision 1.1.1.1 2001/05/18 23:14:05 mb
// Move from private repository to open source repository
//
// MS 92
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/genber.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/any/genber.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
// $Log: genber.C,v $
// Revision 1.1.1.1 2001/05/18 23:14:05 mb
// Move from private repository to open source repository
#
# MS 92
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/any/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
.../c++_lib/inc/asn_len.h to check a global flag.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/simple/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
// AUTHOR: Mike Sample
// DATE: Aug 92
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/example.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/simple/example.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
// $Log: example.C,v $
// Revision 1.1.1.1 2001/05/18 23:14:05 mb
// Move from private repository to open source repository
//
// MS 92
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/genber.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/simple/genber.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
// $Log: genber.C,v $
// Revision 1.1.1.1 2001/05/18 23:14:05 mb
// Move from private repository to open source repository
#
# WARNING: this makefile isn't safe for parallel making!
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/simple/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
this problem the with value "private" in rfc1155-smi.asn1.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/snmp/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/snmp/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
# c++-examples/snmp/makefile
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/snmp/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/snmp/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
and and compared with the original value.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/test-lib/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/test-lib/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
# c++-examples/test-lib/makefile
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/test-lib/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/test-lib/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
// c++_examples/test_lib/test_lib.C
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/test-lib/test-lib.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-examples/test-lib/test-lib.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
// $Log: test-lib.C,v $
// Revision 1.1.1.1 2001/05/18 23:14:05 mb
// Move from private repository to open source repository
documentation.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
//
//
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp,v 1.4 2002/03/21 05:38:44 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp,v 1.4 2002/03/21 05:38:44 dmitch Exp $
// $Log: asn-any.cpp,v $
// Revision 1.4 2002/03/21 05:38:44 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp,v 1.4 2002/03/21 05:38:44 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp,v 1.4 2002/03/21 05:38:44 dmitch Exp $
// $Log: asn-bits.cpp,v $
// Revision 1.4 2002/03/21 05:38:44 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
// $Log: asn-bool.cpp,v $
// Revision 1.3 2002/03/21 05:38:44 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
// $Log: asn-enum.cpp,v $
// Revision 1.3 2002/03/21 05:38:44 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
// $Log: asn-int.cpp,v $
// Revision 1.3 2002/03/21 05:38:44 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-list.cpp,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
// $Log: asn-null.cpp,v $
// Revision 1.3 2002/03/21 05:38:44 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
// $Log: asn-octs.cpp,v $
// Revision 1.3 2002/03/21 05:38:44 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp,v 1.4 2002/03/21 05:38:45 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp,v 1.4 2002/03/21 05:38:45 dmitch Exp $
// $Log: asn-oid.cpp,v $
// Revision 1.4 2002/03/21 05:38:45 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp,v 1.4 2002/03/21 05:38:45 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp,v 1.4 2002/03/21 05:38:45 dmitch Exp $
// $Log: asn-real.cpp,v $
// Revision 1.4 2002/03/21 05:38:45 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
//
// MS 92
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp,v 1.3 2002/03/21 05:38:45 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp,v 1.3 2002/03/21 05:38:45 dmitch Exp $
// $Log: asn-type.cpp,v $
// Revision 1.3 2002/03/21 05:38:45 dmitch
// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/hash.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/hash.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: hash.cpp,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// file: .../c++-lib/src/meta.C
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/meta.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/meta.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: meta.cpp,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/print.cpp,v 1.4 2001/06/28 22:49:58 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/print.cpp,v 1.4 2001/06/28 22:49:58 mb Exp $
// $Log: print.cpp,v $
// Revision 1.4 2001/06/28 22:49:58 mb
// Saved 4 bytes of data when compiling with -DNDEBUG
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp,v 1.2 2002/02/07 04:30:04 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp,v 1.2 2002/02/07 04:30:04 mb Exp $
// $Log: str-stk.cpp,v $
// Revision 1.2 2002/02/07 04:30:04 mb
// Fixes required to build with gcc3.
// file: .../c++-lib/src/tcl-if.C
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: tcl-if.cpp,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
/*
* snacced - Snacc_Init added to the default tkXAppInit.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
* $Log: tkAppInit.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:06 mb
* Move from private repository to open source repository
*/
#ifndef lint
-static char rcsid[] = "$Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $ SPRITE (Berkeley)";
+static char rcsid[] = "$Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $ SPRITE (Berkeley)";
#endif /* not lint */
#include <tk.h>
//
//
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-any.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-any.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-any.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-bits.h,v 1.2 2001/06/28 23:36:11 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-bits.h,v 1.2 2001/06/28 23:36:11 dmitch Exp $
// $Log: asn-bits.h,v $
// Revision 1.2 2001/06/28 23:36:11 dmitch
// Removed SccsId statics. numToHexCharTblG table now const. Radar 2705410.
//
//
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-bool.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-bool.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-bool.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-buf.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-buf.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-buf.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-config.h,v 1.7 2002/06/12 18:36:31 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-config.h,v 1.7 2002/06/12 18:36:31 dmitch Exp $
// $Log: asn-config.h,v $
// Revision 1.7 2002/06/12 18:36:31 dmitch
// Radar 2951933: Avoid including iostream in asn-config.h for NDEBUG builds.
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-enum.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-enum.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-enum.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
//
//
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-incl.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-incl.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-incl.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-int.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-int.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-int.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-len.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-len.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-len.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-list.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-list.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-list.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-null.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-null.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-null.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
//
//
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-octs.h,v 1.2 2002/04/18 18:58:08 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-octs.h,v 1.2 2002/04/18 18:58:08 dmitch Exp $
// $Log: asn-octs.h,v $
// Revision 1.2 2002/04/18 18:58:08 dmitch
// Radar 2904404 - avoid deprecated iostream.h
//
//
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-oid.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-oid.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-oid.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-real.h,v 1.2 2001/06/21 21:57:00 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-real.h,v 1.2 2001/06/21 21:57:00 dmitch Exp $
// $Log: asn-real.h,v $
// Revision 1.2 2001/06/21 21:57:00 dmitch
// Avoid global const PLUS_INFINITY, MINUS_INFINITY
//
//
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-tag.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-tag.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-tag.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
//
// MS 92
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-type.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/asn-type.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: asn-type.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/hash.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/hash.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: hash.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
/*
* file: .../c++-lib/inc/init.h
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/init.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/init.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
* $Log: init.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:06 mb
* Move from private repository to open source repository
// file: .../c++-lib/inc/meta.h
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/meta.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/meta.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: meta.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/print.h,v 1.3 2001/06/27 23:57:51 dmitch Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/print.h,v 1.3 2001/06/27 23:57:51 dmitch Exp $
// $Log: print.h,v $
// Revision 1.3 2001/06/27 23:57:51 dmitch
// Reimplement partial fix for Radar 2664258: Print() routines are now empty stubs in NDEBUG config.
*
*
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/snacc.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/snacc.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
* $Log: snacc.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:06 mb
* Move from private repository to open source repository
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/str-stk.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/str-stk.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: str-stk.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
// file: .../c++-lib/inc/tcl-if.h
//
-// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/tcl-if.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/inc/tcl-if.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
// $Log: tcl-if.h,v $
// Revision 1.1.1.1 2001/05/18 23:14:06 mb
// Move from private repository to open source repository
#
# MS 92
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:05 mb
# Move from private repository to open source repository
/*
* snacced - Snacc_Init added to the default tkXAppInit.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: tkAppInit.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
*/
#ifndef lint
-static char rcsid[] = "$Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $ SPRITE (Berkeley)";
+static char rcsid[] = "$Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $ SPRITE (Berkeley)";
#endif /* not lint */
#include <tk.h>
add all the mappings to the hash table(s).
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/any/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
* AUTHOR: Mike Sample
* DATE: Mar 92
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/example.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/any/example.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: example.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
*
* MS 92
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/genber.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/any/genber.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: genber.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
#
# MS 92
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/any/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
# c-examples/makefile
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
macros in snacc/c_lib/asn_len.h to check a global flag.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/simple/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
* AUTHOR: Mike Sample
* DATE: Mar 92
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/expbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/simple/expbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: expbuf-ex.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
*
* MS 92
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/genber.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/simple/genber.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: genber.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
#
# WARNING: this makefile isn't safe for parallel making!
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/simple/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
* AUTHOR: Mike Sample
* DATE: Mar 92
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/minbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/simple/minbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: minbuf-ex.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
* AUTHOR: Mike Sample
* DATE: Mar 92
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/sbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/simple/sbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: sbuf-ex.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
type (ANY DEFINED BY types should work automatically).
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/snmp/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/snmp/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
# c-examples/snmp/makefile
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/snmp/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/snmp/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
and and compared with the original value.
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/test-lib/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/test-lib/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
# c-examples/test-lib/makefile
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/test-lib/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/test-lib/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
*
* MS 92
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/test-lib/test-lib.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-examples/test-lib/test-lib.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
* $Log: test-lib.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:07 mb
* Move from private repository to open source repository
link with libasn1csbuf.a).
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-any.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-any.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-any.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-bits.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-bits.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-bits.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-bool.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-bool.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-bool.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-enum.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-enum.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-enum.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-incl.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-incl.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-incl.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-int.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-int.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-int.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-len.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-len.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-len.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-list.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-list.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-list.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-null.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-null.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-null.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-octs.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-octs.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-octs.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-oid.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-oid.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-oid.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-real.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-real.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-real.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
*
* INSERT_VDA_COMMENTS
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-tag.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/asn-tag.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-tag.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/exp-buf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/exp-buf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: exp-buf.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/hash.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/hash.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: hash.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/mem.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/mem.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: mem.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/min-buf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/min-buf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: min-buf.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: nibble-alloc.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/print.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/print.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: print.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/sbuf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/sbuf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: sbuf.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/str-stk.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/str-stk.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: str-stk.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-dec.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/tbl-dec.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tbl-dec.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-enc.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/tbl-enc.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tbl-enc.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-free.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/tbl-free.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tbl-free.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-gen-c-hdr.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/tbl-gen-c-hdr.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tbl-gen-c-hdr.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-incl.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/tbl-incl.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tbl-incl.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-print.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/tbl-print.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tbl-print.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-util.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/inc/tbl-util.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tbl-util.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
#
# MS 92
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:07 mb
# Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-any.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-any.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-any.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-bits.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-bits.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-bits.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-bool.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-bool.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-bool.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-enum.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-enum.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-enum.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-int.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-int.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-int.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-len.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-len.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-len.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-list.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-list.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-list.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-null.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-null.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-null.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-octs.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-octs.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-octs.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-oid.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-oid.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-oid.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-real.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-real.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-real.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-tag.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-tag.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: asn-tag.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/exp-buf.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/exp-buf.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: exp-buf.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/hash.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/hash.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: hash.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/nibble-alloc.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/nibble-alloc.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: nibble-alloc.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/print.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/print.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: print.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/str-stk.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/str-stk.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: str-stk.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
related src: core/snacc.c back_ends/*
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/README,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/README,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:08 mb
# Move from private repository to open source repository
*
* INSERT_VDA_COMMENTS
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-any.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-any.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* INSERT_VDA_COMMENTS
*
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c,v 1.4 2002/03/21 05:38:53 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c,v 1.4 2002/03/21 05:38:53 dmitch Exp $
* $Log: gen-code.c,v $
* Revision 1.4 2002/03/21 05:38:53 dmitch
* Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-code.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.c,v 1.3 2001/06/25 21:51:10 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.c,v 1.3 2001/06/25 21:51:10 dmitch Exp $
* $Log: gen-vals.c,v $
* Revision 1.3 2001/06/25 21:51:10 dmitch
* Avoid instantiating AsnInt constants; use #define instead. Partial fix for Radar 2664258.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.h,v 1.3 2001/06/25 21:51:10 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.h,v 1.3 2001/06/25 21:51:10 dmitch Exp $
* $Log: gen-vals.h,v $
* Revision 1.3 2001/06/25 21:51:10 dmitch
* Avoid instantiating AsnInt constants; use #define instead. Partial fix for Radar 2664258.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: kwd.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: kwd.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: rules.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: rules.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
*
* INSERT_VDA_COMMENTS
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: types.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: types.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-any.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-any.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-any2.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-code.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-code.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-code2.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-dec.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-dec.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-enc.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-enc.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-free.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-free.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-print.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-print.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-type.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-type.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-vals.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-vals.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-vals2.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: kwd.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: kwd.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: kwd2.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: rules.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: rules.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: rules2.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: type-info.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: type-info.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: util.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: util.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/cond.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/cond.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: cond.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/cond.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/cond.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: cond.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-any.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-any.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-code.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-code.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-vals.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: gen-vals.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: rules.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: rules.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: types.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: types.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/str-util.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/str-util.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: str-util.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/str-util.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/str-util.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: str-util.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
*
* INSERT_VDA_COMMENTS
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/tag-util.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/tag-util.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
* $Log: tag-util.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:08 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/tag-util.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/back-ends/tag-util.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
* $Log: tag-util.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:09 mb
* Move from private repository to open source repository
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/define.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/define.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: define.c,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/define.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/define.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: define.h,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/dependency.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/dependency.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: dependency.c,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/dependency.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/dependency.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: dependency.h,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/do-macros.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/do-macros.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: do-macros.c,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/do-macros.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/do-macros.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: do-macros.h,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/err-chk.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/err-chk.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: err-chk.c,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/err-chk.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/err-chk.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: err-chk.h,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/exports.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/exports.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: exports.c,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/exports.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/exports.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
* $Log: exports.h,v $
* Revision 1.1 2001/06/20 21:27:56 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/gen-tbls.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/gen-tbls.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: gen-tbls.c,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/gen-tbls.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/gen-tbls.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: gen-tbls.h,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
/* A lexical scanner generated by flex */
/* Scanner skeleton version:
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
*/
#define FLEX_SCANNER
/* (at your option) any later version. */
/* these comments must only be a single line each - lex blows it otherwise */
/* due to this claim, the rcs log is at the end of this file. */
-/* $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $ */
+/* $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $ */
/* This lex spec should compile under either lex or flex. */
/* There are three modes to the lexical analyzer, INITIAL, MACRO_DEF, */
/* and BRACE_BAL. INITIAL is the normal mode. MACRO_DEF is used by */
/* these comments must only be a single line each - lex blows it otherwise */
/* due to this claim, the rcs log is at the end of this file. */
-/* $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.l,v 1.1 2001/06/20 21:27:57 dmitch Exp $ */
+/* $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.l,v 1.1 2001/06/20 21:27:57 dmitch Exp $ */
/* This lex spec should compile under either lex or flex. */
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-stuff.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/lex-stuff.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: lex-stuff.h,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lib-types.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/lib-types.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: lib-types.c,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lib-types.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/lib-types.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: lib-types.h,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-types.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/link-types.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: link-types.c,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-types.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/link-types.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: link-types.h,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-values.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/link-values.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: link-values.c,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-values.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/link-values.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: link-values.h,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/mem.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/mem.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: mem.c,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* PURPOSE. See the GNU General Public License and GNU Library General
* Public License for more details.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/meta.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/meta.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: meta.c,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* PURPOSE. See the GNU General Public License and GNU Library General
* Public License for more details.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/meta.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/meta.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
* $Log: meta.h,v $
* Revision 1.1 2001/06/20 21:27:57 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/normalize.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/normalize.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: normalize.c,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/normalize.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/normalize.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: normalize.h,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/oid.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/oid.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: oid.c,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/oid.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/oid.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: oid.h,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/parse-asn1.y,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/parse-asn1.y,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: parse-asn1.y,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/parser.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/parser.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: parser.h,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/print.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/print.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: print.c,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/print.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/print.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: print.h,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/print2.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/print2.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: print2.c,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/recursive.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/recursive.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
* $Log: recursive.c,v $
* Revision 1.1 2001/06/20 21:27:58 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/recursive.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/recursive.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
* $Log: recursive.h,v $
* Revision 1.1 2001/06/20 21:27:59 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/snacc-util.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/snacc-util.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
* $Log: snacc-util.c,v $
* Revision 1.1 2001/06/20 21:27:59 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/snacc-util.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/snacc-util.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
* $Log: snacc-util.h,v $
* Revision 1.1 2001/06/20 21:27:59 dmitch
* Adding missing snacc compiler files.
*
* INSERT_VDA_COMMENTS
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/snacc.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/snacc.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
* $Log: snacc.c,v $
* Revision 1.1 2001/06/20 21:27:59 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/val-parser.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/val-parser.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
* $Log: val-parser.c,v $
* Revision 1.1 2001/06/20 21:27:59 dmitch
* Adding missing snacc compiler files.
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/val-parser.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/core/val-parser.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
* $Log: val-parser.h,v $
* Revision 1.1 2001/06/20 21:27:59 dmitch
* Adding missing snacc compiler files.
# Mike Sample
# 1992
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/makefile,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/compiler/makefile,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:08 mb
# Move from private repository to open source repository
/*
* file: acconfig.h
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/config.h.in,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/config.h.in,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
* $Log: config.h.in,v $
* Revision 1.1.1.1 2001/05/18 23:14:04 mb
* Move from private repository to open source repository
% file: .../doc/asn1-defs.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/asn1-defs.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/asn1-defs.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: asn1-defs.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/c++-gen.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c++-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/c++-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: c++-gen.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/c++-lib.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c++-lib.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/c++-lib.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: c++-lib.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/c-gen.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/c-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: c-gen.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/c-lib.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c-lib.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/c-lib.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: c-lib.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/coding.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/coding.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/coding.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: coding.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/corba.bib
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/corba.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/corba.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: corba.bib,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/design.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/design.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/design.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: design.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/editor.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/editor.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/editor.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: editor.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/future-work.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/future-work.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/future-work.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: future-work.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/idl-gen.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/idl-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/idl-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: idl-gen.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/intro-1.1.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/intro-1.1.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/intro-1.1.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: intro-1.1.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/intro-1.2.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/intro-1.2.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/intro-1.2.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: intro-1.2.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
#
# if latex bombs unexplainably, try 'make clean' followed by 'make'
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
% file: .../doc/makefile.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/makefile.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/makefile.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: makefile.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/meta.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/meta.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/meta.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: meta.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/misc-hyph.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/misc-hyph.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/misc-hyph.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: misc-hyph.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
.\" Copyright (c) 1993 by Mike Sample and UBC
.\" See section COPYING for conditions for redistribution
-.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/mkchdr.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/mkchdr.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
.\" $Log: mkchdr.1,v $
.\" Revision 1.1.1.1 2001/05/18 23:14:10 mb
.\" Move from private repository to open source repository
% file: .../doc/modifying.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/modifying.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/modifying.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: modifying.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
.\" Copyright (c) 1993 by Mike Sample and UBC
.\" See section COPYING for conditions for redistribution
-.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/ptbl.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/ptbl.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
.\" $Log: ptbl.1,v $
.\" Revision 1.1.1.1 2001/05/18 23:14:10 mb
.\" Move from private repository to open source repository
.\" Copyright (c) 1993 by Mike Sample and UBC
.\" See section COPYING for conditions for redistribution
-.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/pval.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/pval.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
.\" $Log: pval.1,v $
.\" Revision 1.1.1.1 2001/05/18 23:14:10 mb
.\" Move from private repository to open source repository
.\" Copyright (c) 1993 by Mike Sample and UBC
.\" See section COPYING for conditions for redistribution
-.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/snacc.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
.\" $Log: snacc.1,v $
.\" Revision 1.1.1.1 2001/05/18 23:14:10 mb
.\" Move from private repository to open source repository
% file: .../doc/snacc.bib
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/snacc.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: snacc.bib,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
'\" This manual page, except for the introductory troff macros, is
'\" Copyright (c) 1995 by Robert Joop.
'\"
-'\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.n,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+'\" $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/snacc.n,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
'\" $Log: snacc.n,v $
'\" Revision 1.1.1.1 2001/05/18 23:14:10 mb
'\" Move from private repository to open source repository
% file: .../doc/snacc.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/snacc.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: snacc.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
'\" This manual page, except for the introductory troff macros, is
'\" Copyright (c) 1995 by Robert Joop.
'\"
-'\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacced.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+'\" $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/snacced.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
'\" $Log: snacced.1,v $
'\" Revision 1.1.1.1 2001/05/18 23:14:10 mb
'\" Move from private repository to open source repository
% file: .../doc/tcl.bib
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/tcl.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/tcl.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: tcl.bib,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/tcl.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/tcl.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/tcl.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: tcl.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
% file: .../doc/ttab.tex
-% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/ttab.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/doc/ttab.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
% $Log: ttab.tex,v $
% Revision 1.1.1.1 2001/05/18 23:14:10 mb
% Move from private repository to open source repository
#
# MS 92
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/makefile,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/makefile,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:04 mb
# Move from private repository to open source repository
#
# INSERT_VDA_COMMENTS
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/makehead.in,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/makehead.in,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
# $Log: makehead.in,v $
# Revision 1.1.1.1 2001/05/18 23:14:04 mb
# Move from private repository to open source repository
#
# INSERT_VDA_COMMENTS
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/makehead.static,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/makehead.static,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
# $Log: makehead.static,v $
# Revision 1.1.1.1 2001/05/18 23:14:04 mb
# Move from private repository to open source repository
# file: maketail
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/maketail,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/maketail,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
# $Log: maketail,v $
# Revision 1.1.1.1 2001/05/18 23:14:04 mb
# Move from private repository to open source repository
*
* INSERT_VDA_COMMENTS
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/snacc.h,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/snacc.h,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
* $Log: snacc.h,v $
* Revision 1.1.1.1 2001/05/18 23:14:04 mb
* Move from private repository to open source repository
A. Look at the manual. (in .../doc/)
#-------------------------------------------------------------------------------
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-example/README,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tbl-example/README,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: README,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
* PURPOSE. See the GNU General Public License and GNU Library General
* Public License for more details.
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-example/example.c,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tbl-example/example.c,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
* $Log: example.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:10 mb
* Move from private repository to open source repository
# file: .../tbl-example/makefile
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-example/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tbl-example/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
#
# MS 93
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-tools/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tbl-tools/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
#
# Makefile for the asnwish
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-asn/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-asn/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
--
-- snacced example, simple types module
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-example/edex0.asn1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-example/edex0.asn1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
-- $Log: edex0.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:10 mb
-- Move from private repository to open source repository
--
-- snacced example, structured types module
--
--- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-example/edex1.asn1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+-- $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-example/edex1.asn1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
-- $Log: edex1.asn1,v $
-- Revision 1.1.1.1 2001/05/18 23:14:10 mb
-- Move from private repository to open source repository
#
# Makefile for the snaccwish
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-example/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-example/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
# file: help.tcl
# toplevel widget to display a help text (modal)
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/help.tcl,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-lib/help.tcl,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: help.tcl,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
# file: .../tcl-lib/makefile
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-lib/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: makefile,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
# file: selbox.tcl
# file and content type selection box (ASN.1)
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/selbox.tcl,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-lib/selbox.tcl,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
# $Log: selbox.tcl,v $
# Revision 1.1.1.1 2001/05/18 23:14:10 mb
# Move from private repository to open source repository
# file: .../tcl-lib/snacced.tcl
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/snacced.tcl,v 1.1.1.1 2001/05/18 23:14:11 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-lib/snacced.tcl,v 1.1.1.1 2001/05/18 23:14:11 mb Exp $
# $Log: snacced.tcl,v $
# Revision 1.1.1.1 2001/05/18 23:14:11 mb
# Move from private repository to open source repository
# file: tkuti.tcl
# miscellaneous Tk utilities.
#
-# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/tkuti.tcl,v 1.1.1.1 2001/05/18 23:14:11 mb Exp $
+# $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-lib/tkuti.tcl,v 1.1.1.1 2001/05/18 23:14:11 mb Exp $
# $Log: tkuti.tcl,v $
# Revision 1.1.1.1 2001/05/18 23:14:11 mb
# Move from private repository to open source repository
* file: tcl-p.c
* purpose: check and return via exit code whether the tcl interface needs to be made
*
- * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-p.c,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+ * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tcl-p.c,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
* $Log: tcl-p.c,v $
* Revision 1.1.1.1 2001/05/18 23:14:05 mb
* Move from private repository to open source repository
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:14:00 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: SecurityServer
ProjectVersion: 17.1
//
void SecurityServerAcl::validate(AclAuthorization auth, const AccessCredentials *cred) const
{
+ instantiateAcl();
SecurityServerEnvironment env(*this);
ObjectAcl::validate(auth, cred, &env);
}
//
// The process-global object
//
+UnixPlusPlus::StaticForkMonitor ClientSession::mHasForked;
ModuleNexus<ClientSession::Global> ClientSession::mGlobal;
bool ClientSession::mSetupSession;
//
void ClientSession::activate()
{
+ // Guard against fork-without-exec. If we are the child of a fork
+ // (that has not exec'ed), our apparent connection to SecurityServer
+ // is just a mirage, and we better reset it.
+ if (mHasForked()) {
+ debug("SSclnt", "process has forked (now pid=%d) - resetting connection object", getpid());
+ mGlobal.reset();
+ }
+
+ // now pick up the (new or existing) connection state
Global &global = mGlobal();
Thread &thread = global.thread();
if (!thread) {
#include <Security/cssmacl.h>
#include <Security/context.h>
#include <Security/globalizer.h>
+#include <Security/unix++.h>
#include <Security/mach++.h>
#include <Security/cssmdb.h>
#include <Security/osxsigning.h>
const void *data, size_t dataLength, void *context);
OSStatus dispatchNotification(const mach_msg_header_t *message,
ConsumeNotification *consumer, void *context);
-
+
private:
void getAcl(AclKind kind, KeyHandle key, const char *tag,
uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc);
const AclOwnerPrototype &edit);
private:
+ static UnixPlusPlus::StaticForkMonitor mHasForked; // global fork indicator
+
struct Thread {
Thread() : registered(false) { }
operator bool() const { return registered; }
# Created and modified by checkpoint; do not edit
# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:53 mb Exp $
-# $Name: Security-54~1 $
+# $Name: $
ProjectName: cdsa
ProjectVersion: 21
*/
typedef uint32 CSSM_APPLE_TP_ACTION_FLAGS;
enum {
- CSSM_TP_ACTION_ALLOW_EXPIRED = 0x00000001, // allow expired certs
+ CSSM_TP_ACTION_ALLOW_EXPIRED = 0x00000001, // allow expired certs
+ CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT = 0x00000008, // allow expired roots
/* other flags TBD */
};
CssmDataContainer dataBlob(allocator());
DbUniqueRecordImpl::get(NULL, &dataBlob);
- // @@@ Use transactions.
+ // delete data part first:
+ // (1) don't leave data without keys around
+ // (2) delete orphaned data anyway
+ DbUniqueRecordImpl::deleteRecord();
+
+ // @@@ Use transactions?
if (SSGroupImpl::isGroup(dataBlob))
- {
+ try {
// Get the group for dataBlob
SSGroup group(database(), dataBlob);
- // Delete the group
- // @@@ What if the group is shared?
+ // Delete the group (key)
group->deleteKey(cred);
+ } catch (const CssmError &err) {
+ switch (err.cssmError()) {
+ case CSSMERR_DL_RECORD_NOT_FOUND:
+ // Zombie item (no group key). Finally at peace! No error
+ break;
+ default:
+ throw;
+ }
}
-
- // Delete the record.
- DbUniqueRecordImpl::deleteRecord();
}
void
if (!mTable)
CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+#if RECORDVERSIONCHECK
const RecordId aRecordId = MetaRecord::unpackRecordId(mTable->getRecordSection(aRecordNumber));
if (aRecordId.mRecordVersion != inRecordId.mRecordVersion)
CssmError::throwMe(CSSMERR_DL_RECORD_MODIFIED);
+#endif
// Schedule the record for deletion
if (!mDeletedSet.insert(aRecordNumber).second)
if (aRecordId.mCreateVersion != inRecordId.mCreateVersion)
CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+#if RECORDVERSIONCHECK
if (aRecordId.mRecordVersion != inRecordId.mRecordVersion)
CssmError::throwMe(CSSMERR_DL_RECORD_MODIFIED);
+#endif
// Remove the inserted (but uncommited) record. It should already be in mDeletedSet
// if it existed previously in mTable.
if (aRecordId.mCreateVersion != inRecordId.mCreateVersion)
CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+#if RECORDVERSIONCHECK
// Is the record we that our update is based on current?
if (aRecordId.mRecordVersion != inRecordId.mRecordVersion)
CssmError::throwMe(CSSMERR_DL_STALE_UNIQUE_RECORD);
+#endif
// Update the actual packed record.
auto_ptr<WriteSection> aDbRecord(new WriteSection());
mWriteFile(nil),
mWriteFilename(mReadFilename + ",") // XXX Do some more work here like resolving symlinks/aliases etc.
{
+ debug("atomicfile", "%p construct name=%s", this, mReadFilename.c_str());
// We only support databases with string names of non-zero length.
if (inDbName.dbLocation() != nil || inDbName.dbName().length() == 0)
CssmError::throwMe(CSSMERR_DL_INVALID_DB_LOCATION);
AtomicFile::~AtomicFile()
{
// Assume there are no more running theads in this object.
+ debug("atomicfile", "%p destroyed", this);
// Try hard to clean up as much as possible.
try
void
AtomicFile::close()
{
+ debug("atomicfile", "%p close", this);
StLock<Mutex> _(mReadLock);
// If we have no read file we have nothing to close.
AtomicFile::VersionId
AtomicFile::commit()
{
+ debug("atomicfile", "%p commit", this);
StLock<Mutex> _(mReadLock);
if (mWriteFile == nil)
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
// Close all unused files (in particular aOpenFile) and remove them from mOpenFileMap
endWrite();
+ debug("atomicfile", "%p commit done", this);
return aVersionId;
}
catch (...)
unlink(mWriteFilename);
}catch(...) {}
endWrite();
+ debug("atomicfile", "%p commit failed, rethrowing", this);
throw;
}
}
void
AtomicFile::rollback()
{
+ debug("atomicfile", "%p rollback", this);
StLock<Mutex> _(mReadLock);
if (mWriteFile == nil)
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
if (mCreating)
unlink(mReadFilename);
endWrite();
+ debug("atomicfile", "%p rollback complete", this);
}
catch(...)
{
unlink(mWriteFilename);
}catch(...) {}
endWrite();
+ debug("atomicfile", "%p rollback failed, rethrowing", this);
throw;
}
}
flags = O_RDONLY;
mState = Read;
}
+ debug("atomicfile", "%p openfile(%s,%s%s,%d,0x%x) -> flags=0x%x, state=%d",
+ this, inFilename.c_str(), write ? "write" : "read", lock ? ",lock" : "",
+ inVersionId, mode, flags, mState);
mFileRef = ::open(inFilename.c_str(), flags, mode);
if (mFileRef == -1)
{
int error = errno;
+ debug("atomicfile", "%p openfile open failed(errno=%d)", this, error);
#if _USE_IO == _USE_IO_POSIX
// Do the obvious error code translations here.
// Now try the open again.
mFileRef = ::open(inFilename.c_str(), flags, mode);
+ debug("atomicfile", "%p openfile reopen %s (%d)",
+ this, (mFileRef == -1) ? "failed" : "ok", errno);
error = mFileRef == -1 ? errno : 0;
if (error == ENOENT)
CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED);
void
AtomicFile::OpenFile::close()
{
+ IFDEBUG(if (mState != Closed) debug("atomicfile", "%p openfile closing(ref=%d)",
+ this, mFileRef));
int error = 0;
if (mAddress != NULL)
{
#if _USE_IO == _USE_IO_POSIX
+ debug("atomicfile", "%p openfile is unmapping %p:%ld", this, mAddress, mLength);
if (::munmap(const_cast<uint8 *>(mAddress), mLength) == -1)
error = errno;
#else
+ debug("atomicfile", "%p openfile deleting %p", this, mAddress);
delete[] mAddress;
#endif
const CssmData *inData,
CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
{
+ debug("dbsession", "%p DataInsert(%lx,%lx)", this, inDbHandle, inRecordType);
DbContext &aDbContext = findDbContext(inDbHandle);
outUniqueId = aDbContext.mDatabase.dataInsert(aDbContext, inRecordType, inAttributes, inData);
}
DatabaseSession::DataDelete(CSSM_DB_HANDLE inDbHandle,
const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
{
+ debug("dbsession", "%p DataDelete(%lx)", this, inDbHandle);
DbContext &aDbContext = findDbContext(inDbHandle);
aDbContext.mDatabase.dataDelete(aDbContext, inUniqueRecordIdentifier);
}
const CssmData *inDataToBeModified,
CSSM_DB_MODIFY_MODE inModifyMode)
{
+ debug("dbsession", "%p DataModify(%lx,%lx)", this, inDbHandle, inRecordType);
DbContext &aDbContext = findDbContext(inDbHandle);
aDbContext.mDatabase.dataModify(aDbContext, inRecordType, inoutUniqueRecordIdentifier,
inAttributesToBeModified, inDataToBeModified, inModifyMode);
CssmData *inoutData,
CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
{
+ debug("dbsession", "%p DataGetFirst(%lx)", this, inDbHandle);
DbContext &aDbContext = findDbContext(inDbHandle);
return aDbContext.mDatabase.dataGetFirst(aDbContext, inQuery,
CssmData *inoutData,
CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
{
+ debug("dbsession", "%p DataGetNext(%lx)", this, inDbHandle);
DbContext &aDbContext = findDbContext(inDbHandle);
return aDbContext.mDatabase.dataGetNext(aDbContext, inResultsHandle, inoutAttributes,
DatabaseSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle,
CSSM_HANDLE inResultsHandle)
{
+ debug("dbsession", "%p DataAbortQuery(%lx)", this, inDbHandle);
DbContext &aDbContext = findDbContext(inDbHandle);
aDbContext.mDatabase.dataAbortQuery(aDbContext, inResultsHandle);
}
CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
CssmData *inoutData)
{
+ debug("dbsession", "%p DataGetFromUniqueId(%lx)", this, inDbHandle);
DbContext &aDbContext = findDbContext(inDbHandle);
aDbContext.mDatabase.dataGetFromUniqueRecordId(aDbContext, inUniqueRecord,
inoutAttributes, inoutData);
{
//@@@ if we wanted to dispose of pending task objects, we'd have
//@@@ to keep a set of them and delete them explicitly here
+#if BUG_2998157
+ // @@@ bug 2998157 does not clear slots on delete or allocate. Leak them for now
pthread_key_delete(mKey);
+#endif //BUG_2998157
}
#endif
//
// Per-thread pointers are patterned after the pthread TLS (thread local storage)
// facility.
+// Let's be clear on what gets destroyed when, here. Following the pthread lead,
+// when a thread dies its PerThreadPointer object(s) are properly destroyed.
+// However, if a PerThreadPointer itself is destroyed, NOTHING HAPPENS. Yes, there are
+// reasons for this. This is not (on its face) a bug, so don't yell. But be aware...
//
#if _USE_THREADS == _USE_PTHREADS
class PerThreadPointer {
public:
PerThreadPointer(bool cleanup = true) : mCleanup(cleanup) { }
- ~PerThreadPointer() { if (mCleanup) delete mValue; }
+ ~PerThreadPointer() { /* no cleanup - see comment above */ }
operator bool() const { return mValue != NULL; }
operator T * () const { return mValue; }
T *operator -> () const { return mValue; }
#define _H_UNIXPLUSPLUS
#include <Security/utilities.h>
-#include "timeflow.h"
+#include <Security/timeflow.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
};
+//
+// A ForkMonitor determines whether the current thread is a (fork) child of
+// the thread that last checked it. Essentially, it checks for pid changes.
+//
+class StaticForkMonitor {
+public:
+ bool operator () () const
+ {
+ if (mLastPid == 0) {
+ mLastPid = getpid();
+ return false;
+ } else if (getpid() != mLastPid) {
+ mLastPid = getpid();
+ return true;
+ }
+ return false;
+ }
+
+protected:
+ mutable pid_t mLastPid;
+};
+
+class ForkMonitor : public StaticForkMonitor {
+public:
+ ForkMonitor() { mLastPid = getpid(); }
+};
+
+
} // end namespace UnixPlusPlus
} // end namespace Security