Beispiel #1
0
/*
 * This constructor, the only one, allocs copies of the key and value
 * SSLBuffers.
 */
static SessionCacheEntry *SessionCacheEntryCreate(
	const tls_buffer *key,
	const tls_buffer *sessionData,
	CFAbsoluteTime expirationTime)
{
    OSStatus serr;

    SessionCacheEntry *entry = sslMalloc(sizeof(SessionCacheEntry));
    if (entry == NULL)
        return NULL;

	serr = SSLCopyBuffer(key, &entry->mKey);
	if(serr) {
        sslFree (entry);
        return NULL;
	}
	serr = SSLCopyBuffer(sessionData, &entry->mSessionData);
	if(serr) {
        SSLFreeBuffer(&entry->mKey);
        sslFree (entry);
        return NULL;
	}

	sslLogSessCacheDebug("SessionCacheEntryCreate(buf,buf) %p", entry);
	entry->mExpiration = expirationTime;

    return entry;
}
/* Set DH parameters - Server only */
int
tls_handshake_set_dh_parameters(tls_handshake_t filter, tls_buffer *params)
{
    assert(filter->isServer);
    assert(params);
    const uint8_t *der, *der_end;
    size_t n;

    der = params->data;
    der_end = params->data + params->length;
    n = ccder_decode_dhparam_n(der, der_end);

    sslFree(filter->dhParams.gp);
    filter->dhParams.gp = sslMalloc(ccdh_gp_size(ccn_sizeof_n(n)));
    if(!filter->dhParams.gp) {
        return errSSLAllocate;
    }

    CCDH_GP_N(filter->dhParams) = n;

    der = ccder_decode_dhparams(filter->dhParams, der, der_end);
    if (der == NULL) {
        return errSSLParam;
    } else {
        return 0;
    }
}
tls_private_key_t tls_private_key_create(tls_private_key_desc_t *desc,
                                         tls_private_key_ctx_t ctx,
                                         tls_private_key_ctx_release ctx_release)
{
    tls_private_key_t key;

    key = sslMalloc(sizeof(struct _tls_private_key));

    if(key==NULL) return NULL;

    key->ctx = ctx;
    key->ctx_release = ctx_release;
    key->desc.type = desc->type;
    switch(desc->type) {
        case tls_private_key_type_rsa:
            key->desc.rsa = desc->rsa;
            break;
        case tls_private_key_type_ecdsa:
            key->desc.ecdsa = desc->ecdsa;
            break;
        default:
            sslFree(key);
            key = NULL;
            break;
    }

    return key;
}
Beispiel #4
0
static void SessionCacheEntryDelete(SessionCacheEntry *entry)
{
	sslLogSessCacheDebug("~SessionCacheEntryDelete() %p", entry);
	SSLFreeBuffer(&entry->mKey);		// no SSLContext
	SSLFreeBuffer(&entry->mSessionData);
    sslFree(entry);
}
/* NOTE: The SigAlgs set here are only used to select which SigAlgs to advertise and select a SigAlg
   for private key operations in TLS 1.2, and is mainly here to allow unit testing. 
   If the peer select a SigAlg that we support but was not set here, coreTLS will still proceed and verify 
   signature. 
 */
int
tls_handshake_set_sigalgs(tls_handshake_t filter, const tls_signature_and_hash_algorithm *sigalgs, unsigned n)
{

    unsigned i;
    unsigned count = 0;

    for(i=0;i<n;i++) {
        if(tls_handshake_sigalg_is_supported(sigalgs[i]))
            count++;
    }

    sslFree(filter->localSigAlgs);
    filter->numLocalSigAlgs = 0;

    filter->localSigAlgs = sslMalloc(count*sizeof(tls_signature_and_hash_algorithm));
    if(!filter->localSigAlgs) {
        return errSSLAllocate;
    }

    for(i=0;i<n;i++) {
        if(tls_handshake_sigalg_is_supported(sigalgs[i])) {
            filter->localSigAlgs[filter->numLocalSigAlgs++]=sigalgs[i];
        }
    }

    assert(filter->numLocalSigAlgs == count);

    return 0;
}
int
tls_handshake_set_curves(tls_handshake_t filter, const uint16_t *curves, unsigned n)
{

    unsigned i;
    unsigned count = 0;
    uint16_t *_c;

    for(i=0;i<n;i++) {
        uint16_t c = curves[i];
        if(tls_handshake_curve_is_supported(c))
            count++;
    }

    sslFree(filter->ecdhCurves);
    filter->ecdhNumCurves=0;

    _c = sslMalloc(count*sizeof(uint16_t));
    if(!_c) {
        return errSSLAllocate;
    }

    filter->ecdhNumCurves = count;
    filter->ecdhCurves = _c;

    for(i=0;i<n;i++) {
        uint16_t c = curves[i];
        if(tls_handshake_curve_is_supported(c))
            *_c++ = c;
    }

    return 0;
}
Beispiel #7
0
int
SSLDecodeBufferList(uint8_t *p, size_t listLen, int itemLenSize, tls_buffer_list_t **list)
{
    int err = 0;

    tls_buffer_list_t *first = NULL;
    tls_buffer_list_t *last = NULL;

    while (listLen > 0)
    {
        size_t itemLen;
        tls_buffer_list_t *item;
        if (listLen < itemLenSize) {
            sslErrorLog("SSLDecodeBufferList: length decode error 2\n");
            err = errSSLProtocol;
            goto errOut;
        }
        itemLen = SSLDecodeInt(p,itemLenSize);
        p += itemLenSize;
        if (listLen < itemLen + itemLenSize) {
            sslErrorLog("SSLDecodeBufferList: length decode error 3\n");
            err = errSSLProtocol;
            goto errOut;
        }
        if(itemLen==0) {
            sslErrorLog("SSLDecodeBufferList: lenght decode error 4 (empty item)\n");
            err = errSSLProtocol;
            goto errOut;
        }
        item = (tls_buffer_list_t *)sslMalloc(sizeof(tls_buffer_list_t));
        if(item == NULL) {
            err = errSSLAllocate;
            goto errOut;
        }
        if ((err = SSLAllocBuffer(&item->buffer, itemLen))) {
            sslFree(item);
            goto errOut;
        }
        item->next = NULL;
        memcpy(item->buffer.data, p, itemLen);
        p += itemLen;

        if(first==NULL) {
            first=item;
            last=item;
        } else {
            last->next=item;
            last=item;
        }
        listLen -= itemLenSize+itemLen;
    }

    *list = first;
    return 0;

errOut:
    tls_free_buffer_list(first);
    return err;
}
Beispiel #8
0
/* free a session */
static OSStatus HMAC_Free(
	HMACContextRef	hmacCtx)
{
	if(hmacCtx != NULL) {
		memset(hmacCtx, 0, sizeof(*hmacCtx));
		sslFree(hmacCtx);
	}
	return noErr;
}
/* Free SSLCertificate array created by parseIncomingCerts */
static int freeCertificates(SSLCertificate *certs)
{
    SSLCertificate *head = certs;
    while(certs) {
        SSLFreeBuffer(&certs->derCert);
        certs = certs->next;
    }
    sslFree(head);
    return 0;
}
int
tls_handshake_set_acceptable_client_auth_type(tls_handshake_t filter, tls_client_auth_type *auth_types, unsigned n)
{
    assert(filter->isServer);
    sslFree(filter->clientAuthTypes);
    filter->clientAuthTypes = sslMalloc(sizeof(tls_client_auth_type)*n);
    if(filter->clientAuthTypes==NULL)
        return errSSLAllocate;
    filter->numAuthTypes = n;
    memcpy(filter->clientAuthTypes, auth_types, sizeof(tls_client_auth_type)*n);
    return 0;
}
/* Set TLS user agent string, for diagnostic purposes */
int
tls_handshake_set_user_agent(tls_handshake_t filter, const char *user_agent)
{
    sslFree(filter->userAgent);
    filter->userAgent = NULL;

    if(user_agent) {
        filter->userAgent = sslMalloc(strlen(user_agent)+1);
        strcpy(filter->userAgent, user_agent);
    }

    return 0;
}
int
SSLFreeBuffer(SSLBuffer *buf)
{   
	if(buf == NULL) {
		sslErrorLog("SSLFreeBuffer: NULL buf!\n");
        check(0);
		return -1;
	}
    sslFree(buf->data);
    buf->data = NULL;
    buf->length = 0;
    return 0;
}
Beispiel #13
0
/*
 * Given raw RSA key bits, cook up a SSLPubKey. Used in
 * Server-initiated key exchange.
 */
OSStatus sslGetPubKeyFromBits(
	SSLContext			*ctx,
	const SSLBuffer		*modulus,
	const SSLBuffer		*exponent,
	SSLPubKey           **pubKey)        // mallocd and RETURNED
{
	if (!pubKey)
		return paramErr;
#if 0
	SSLPubKey *key;
	RSAStatus rsaStatus;
	RSAPubKey apiKey = {
		modulus->data, modulus->length,
		NULL, 0,
		exponent->data, exponent->length
	};

	key = sslMalloc(sizeof(*key));
	rsaStatus = rsaInitPubGKey(&apiKey, &key->rsaKey);
	if (rsaStatus) {
		sslFree(key);
		return rsaStatusToSSL(rsaStatus);
	}

	*pubKey = key;
	return noErr;
#else
	check(pubKey);
	SecRSAPublicKeyParams params = {
		modulus->data, modulus->length,
		exponent->data, exponent->length
	};
#if SSL_DEBUG
	sslDebugLog("Creating RSA pub key from modulus=%p len=%lu exponent=%p len=%lu\n",
			(uintptr_t)modulus->data, modulus->length,
			(uintptr_t)exponent->data, exponent->length);
#endif
	SecKeyRef key = SecKeyCreateRSAPublicKey(NULL, (const uint8_t *)&params,
			sizeof(params), kSecKeyEncodingRSAPublicParams);
	if (!key) {
		sslErrorLog("sslGetPubKeyFromBits: SecKeyCreateRSAPublicKey failed\n");
		return errSSLCrypto;
	}
#if SSL_DEBUG
	size_t blocksize = SecKeyGetBlockSize(key);
	sslDebugLog("sslGetPubKeyFromBits: RSA pub key block size=%lu\n", blocksize);
#endif
	*pubKey = (SSLPubKey*)key;
	return noErr;
#endif
}
void *
sslRealloc(void *oldPtr, size_t oldLen, size_t newLen)
{
    /* _REALLOC is in sys/malloc.h but is only exported in debug kernel */
    /* return _REALLOC(oldPtr, newLen, M_TEMP, M_NOWAIT); */

    /* FIXME */
    void *newPtr;
    if(newLen>oldLen) {
        newPtr=sslMalloc(newLen);
        if(newPtr) {
            memcpy(newPtr, oldPtr, oldLen);
            sslFree(oldPtr);
        }
    } else {
        newPtr=oldPtr;
    }
    return newPtr;
}
int SSLAllocCopyBuffer(
	const SSLBuffer *src, 
	SSLBuffer **dst)		// buffer and data mallocd and returned 
{   
	int serr;
	
	SSLBuffer *rtn = (SSLBuffer *)sslMalloc(sizeof(SSLBuffer));
	if(rtn == NULL) {
        sslErrorLog("SSLAllocCopyBuffer: NULL buf!\n");
        check(0);
		return -1;
	}
	serr = SSLCopyBuffer(src, rtn);
	if(serr) {
		sslFree(rtn);
	}
	else {
		*dst = rtn;
	}
	return serr;
}
static int
tls_handshake_set_ciphersuites_internal(tls_handshake_t filter, tls_handshake_config_t config, const uint16_t *ciphersuites, unsigned n)
{
    unsigned i;
    unsigned count = 0;
    uint16_t *_cs;

    for(i=0;i<n;i++) {
        uint16_t cs = ciphersuites[i];
        if(tls_handshake_ciphersuite_is_supported(filter->isServer, filter->isDTLS, cs) &&
           tls_handshake_ciphersuite_is_allowed(config, cs))
        {
            count++;
        }
    }

    sslFree(filter->enabledCipherSuites);
    filter->numEnabledCipherSuites=0;

    _cs = sslMalloc(count*sizeof(uint16_t));
    if(!_cs) {
        return errSSLAllocate;
    }

    filter->numEnabledCipherSuites = count;
    filter->enabledCipherSuites = _cs;

    for(i=0;i<n;i++) {
        uint16_t cs = ciphersuites[i];
        if(tls_handshake_ciphersuite_is_supported(filter->isServer, filter->isDTLS, cs) &&
           tls_handshake_ciphersuite_is_allowed(config, cs))
        {
            *_cs++ = cs;
        }
    }

    sslAnalyzeCipherSpecs(filter);
    return 0;
}
Beispiel #17
0
int
SSLProcessCertificateRequest(tls_buffer message, tls_handshake_t ctx)
{
    unsigned        i;
    unsigned	    typeCount;
    unsigned		shListLen = 0;
    UInt8           *charPtr;
    unsigned		dnListLen;
	unsigned		dnLen;
    tls_buffer		dnBuf;
    DNListElem		*dn;
	int		err;

    /*
     * Cert request only happens in during client authentication.
     * Application can send a client cert if they have an appropriate one.
     * coreTLS does not ensure the client cert is appropriate.
     */

    unsigned minLen = (sslVersionIsLikeTls12(ctx)) ? 5 : 3;
    if (message.length < minLen) {
    	sslErrorLog("SSLProcessCertificateRequest: length decode error 1\n");
        return errSSLProtocol;
    }
    charPtr = message.data;
    typeCount = *charPtr++;
    if ((typeCount < 1) || (message.length < minLen + typeCount)) {
    	sslErrorLog("SSLProcessCertificateRequest: length decode error 2\n");
        return errSSLProtocol;
    }

    /* Update the server-specified auth types */
    sslFree(ctx->clientAuthTypes);
    ctx->numAuthTypes = typeCount;
    ctx->clientAuthTypes = (tls_client_auth_type *)
                           sslMalloc(ctx->numAuthTypes * sizeof(tls_client_auth_type));
    if(ctx->clientAuthTypes==NULL)
        return errSSLInternal;

    for(i=0; i<ctx->numAuthTypes; i++) {
        sslLogNegotiateDebug("===Server specifies authType %d", (int)(*charPtr));
        ctx->clientAuthTypes[i] = (tls_client_auth_type)(*charPtr++);
    }

    if (sslVersionIsLikeTls12(ctx)) {
        /* Parse the supported_signature_algorithms field added in TLS1.2 */
        shListLen = SSLDecodeInt(charPtr, 2);
        charPtr += 2;
        if ((shListLen < 2) || (message.length < minLen + typeCount + shListLen)) {
            sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n");
            return errSSLProtocol;
        }

        if (shListLen & 1) {
            sslErrorLog("SSLProcessCertificateRequest: signAlg len odd\n");
            return errSSLProtocol;
        }

        sslFree(ctx->peerSigAlgs);
        ctx->numPeerSigAlgs = shListLen / 2;
        ctx->peerSigAlgs = (tls_signature_and_hash_algorithm *)
                              sslMalloc((ctx->numPeerSigAlgs) * sizeof(tls_signature_and_hash_algorithm));
        if(ctx->peerSigAlgs==NULL)
            return errSSLInternal;

        for(i=0; i<ctx->numPeerSigAlgs; i++) {
            ctx->peerSigAlgs[i].hash = *charPtr++;
            ctx->peerSigAlgs[i].signature = *charPtr++;
            sslLogNegotiateDebug("===Server specifies sigAlg %d %d",
                                 ctx->peerSigAlgs[i].hash,
                                 ctx->peerSigAlgs[i].signature);
        }
    }

    /* Update the acceptable DNList */
    SSLFreeDNList(ctx->acceptableDNList);
    ctx->acceptableDNList=NULL;

    dnListLen = SSLDecodeInt(charPtr, 2);
    charPtr += 2;
    if (message.length != minLen + typeCount + shListLen + 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))))
            return err;
        dn = (DNListElem*)dnBuf.data;
        if ((err = SSLAllocBuffer(&dn->derDN, dnLen)))
        {   SSLFreeBuffer(&dnBuf);
            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);

    return errSSLSuccess;
}
Beispiel #18
0
/*
 * Given a SSLCertificate cert, obtain its public key as a SSLPubKey.
 * Caller must sslFreePubKey and free the SSLPubKey itself.
 */
OSStatus sslPubKeyFromCert(
	SSLContext 				*ctx,
	const SSLCertificate	*cert,
	SSLPubKey               **pubKey) 		// RETURNED
{
    DERItem der;
    DERSignedCertCrl signedCert;
    DERTBSCert tbsCert;
	DERSubjPubKeyInfo pubKeyInfo;
	DERByte numUnused;
    DERItem pubKeyPkcs1;
    SSLPubKey *key;
	DERReturn drtn;
    RSAStatus rsaStatus;

    assert(cert);
	assert(pubKey != NULL);

    der.data = cert->derCert.data;
    der.length = cert->derCert.length;

	/* top level decode */
	drtn = DERParseSequence(&der, DERNumSignedCertCrlItemSpecs,
		DERSignedCertCrlItemSpecs, &signedCert, sizeof(signedCert));
	if(drtn)
		return errSSLBadCert;

	/* decode the TBSCert - it was saved in full DER form */
	drtn = DERParseSequence(&signedCert.tbs,
		DERNumTBSCertItemSpecs, DERTBSCertItemSpecs,
		&tbsCert, sizeof(tbsCert));
	if(drtn)
		return errSSLBadCert;

	/* sequence we're given: encoded DERSubjPubKeyInfo */
	drtn = DERParseSequenceContent(&tbsCert.subjectPubKey,
		DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs,
		&pubKeyInfo, sizeof(pubKeyInfo));
	if(drtn)
		return errSSLBadCert;

	/* @@@ verify that this is an RSA key by decoding the AlgId */

	/*
	 * The contents of pubKeyInfo.pubKey is a bit string whose contents
	 * are a PKCS1 format RSA key.
	 */
	drtn = DERParseBitString(&pubKeyInfo.pubKey, &pubKeyPkcs1, &numUnused);
	if(drtn)
		return errSSLBadCert;

#if TARGET_OS_IOS
    /* Now we have the public key in pkcs1 format.  Let's make a public key
       object out of it. */
    key = sslMalloc(sizeof(*key));
    rsaStatus = RSA_DecodePubKey(pubKeyPkcs1.data, pubKeyPkcs1.length,
        &key->rsaKey);
	if (rsaStatus) {
		sslFree(key);
	}
#else
	SecKeyRef rsaPubKeyRef = SecKeyCreateRSAPublicKey(NULL,
		pubKeyPkcs1.data, pubKeyPkcs1.length,
		kSecKeyEncodingRSAPublicParams);
	rsaStatus = (rsaPubKeyRef) ? 0 : 1;
	key = (SSLPubKey*)rsaPubKeyRef;
#endif
	if (rsaStatus) {
		return rsaStatusToSSL(rsaStatus);
	}

	*pubKey = key;
	return noErr;
}
void tls_private_key_destroy(tls_private_key_t key)
{
    if(key->ctx_release && key->ctx)
        key->ctx_release(key->ctx);
    sslFree(key);
}
void
tls_handshake_destroy(tls_handshake_t filter)
{
    tls_metric_destroyed(filter);

    /* Free the last handshake message flight */
    SSLResetFlight(filter);

    CloseHash(&SSLHashSHA1, &filter->shaState);
    CloseHash(&SSLHashMD5,  &filter->md5State);
    CloseHash(&SSLHashSHA256,  &filter->sha256State);
    CloseHash(&SSLHashSHA384,  &filter->sha384State);
    CloseHash(&SSLHashSHA512,  &filter->sha512State);

    sslFreePubKey(&filter->peerPubKey);
    sslFreePubKey(&filter->rsaEncryptPubKey);

    SSLFreeBuffer(&filter->fragmentedMessageCache);
    SSLFreeBuffer(&filter->peerID);
    SSLFreeBuffer(&filter->proposedSessionID);
    SSLFreeBuffer(&filter->sessionID);
    SSLFreeBuffer(&filter->sessionTicket);
    SSLFreeBuffer(&filter->externalSessionTicket);
    SSLFreeBuffer(&filter->preMasterSecret);
    SSLFreeBuffer(&filter->dhPeerPublic);
	SSLFreeBuffer(&filter->ecdhPeerPublic);
    SSLFreeBuffer(&filter->npnOwnData);
    SSLFreeBuffer(&filter->npnPeerData);
    SSLFreeBuffer(&filter->alpnOwnData);
    SSLFreeBuffer(&filter->alpnPeerData);
    SSLFreeBuffer(&filter->ownVerifyData);
    SSLFreeBuffer(&filter->peerVerifyData);
    SSLFreeBuffer(&filter->pskIdentity);
    SSLFreeBuffer(&filter->pskSharedSecret);
    SSLFreeBuffer(&filter->peerDomainName);
    SSLFreeBuffer(&filter->ocsp_response);
    SSLFreeBuffer(&filter->ocsp_request_extensions);
    tls_free_buffer_list(filter->ocsp_responder_id_list);
    tls_free_buffer_list(filter->sct_list);

    sslFree(filter->userAgent);
    sslFree(filter->enabledCipherSuites);
    sslFree(filter->requestedCipherSuites);
    sslFree(filter->ecdhCurves);
    sslFree(filter->peerSigAlgs);
    sslFree(filter->localSigAlgs);
    sslFree(filter->clientAuthTypes);
    sslFree(filter->ecdhContext._full);
    sslFree(filter->dhParams.gp);
    sslFree(filter->dhContext._full);
    sslFree(filter->requested_ecdh_curves);

    if(filter->signingPrivKeyRef)
        tls_private_key_destroy(filter->signingPrivKeyRef);
    SSLFreeCertificates(filter->localCert);

    SSLFreeCertificates(filter->peerCert);
    if(!filter->isServer) {
        SSLFreeDNList(filter->acceptableDNList);
    }

    free(filter);
}