Esempio n. 1
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
}
Esempio n. 2
0
static
int tls_handshake_advance_read_cipher_callback(tls_handshake_ctx_t ctx)
{
    SSLContext *myCtx = (SSLContext *)ctx;
    sslDebugLog("%p\n", myCtx);
    return myCtx->recFuncs->advanceReadCipher(myCtx->recCtx);
}
Esempio n. 3
0
static
int tls_handshake_rollback_write_callback(tls_handshake_ctx_t ctx)
{
    SSLContext *myCtx = (SSLContext *)ctx;
    sslDebugLog("%p\n", myCtx);
    return myCtx->recFuncs->rollbackWriteCipher(myCtx->recCtx);
}
Esempio n. 4
0
static int
tls_handshake_advance_write_callback(tls_handshake_ctx_t ctx)
{
    SSLContext *myCtx = (SSLContext *)ctx;
    sslDebugLog("%p\n", myCtx);
    //FIXME: need to filter on cipher too - require missing coretls ciphersuite header */
    bool split = (myCtx->oneByteRecordEnable && (myCtx->negProtocolVersion<=TLS_Version_1_0));
    myCtx->recFuncs->setOption(myCtx->recCtx, kSSLRecordOptionSendOneByteRecord, split);
    return myCtx->recFuncs->advanceWriteCipher(myCtx->recCtx);
}
Esempio n. 5
0
static int
tls_handshake_init_pending_cipher_callback(tls_handshake_ctx_t ctx,
                                                  uint16_t            selectedCipher,
                                                  bool                server,
                                                  SSLBuffer           key)
{
    sslDebugLog("%p, cipher=%04x, server=%d\n", ctx, selectedCipher, server);
    SSLContext *myCtx = (SSLContext *)ctx;
    return myCtx->recFuncs->initPendingCiphers(myCtx->recCtx, selectedCipher, server, key);
}
Esempio n. 6
0
static int
tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx)
{
    SSLContext *myCtx = (SSLContext *)ctx;
    sslDebugLog("%p\n", ctx);

    if(myCtx->cache) {
        tls_cache_empty(myCtx->cache);
    }
    return 0;
}
Esempio n. 7
0
static int
tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey)
{
    int err = errSSLSessionNotFound;
    SSLContext *myCtx = (SSLContext *)ctx;

    sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx, sessionKey.length, sessionKey.data[0]);
    if(myCtx->cache) {
        err = tls_cache_delete_session_data(myCtx->cache, &sessionKey);
    }
    return err;
}
Esempio n. 8
0
static
int tls_handshake_write_callback(tls_handshake_ctx_t ctx, const SSLBuffer data, uint8_t content_type)
{
    SSLContext *myCtx = (SSLContext *)ctx;
    sslDebugLog("%p (rec.len=%zd, ct=%d, d[0]=%d)\n", myCtx, data.length, content_type, data.data[0]);

    SSLRecord rec;

    rec.contents=data;
    rec.contentType=content_type;

    return myCtx->recFuncs->write(myCtx->recCtx,rec);
}
Esempio n. 9
0
static int
tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer sessionData)
{
    int err = errSSLSessionNotFound;
    SSLContext *myCtx = (SSLContext *)ctx;

    sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__, myCtx, sessionKey.length, sessionKey.data[0], sessionData.length);

    if(myCtx->cache) {
        err = tls_cache_save_session_data(myCtx->cache, &sessionKey, &sessionData, myCtx->sessionCacheTimeout);
    }
    return err;
}
Esempio n. 10
0
static int
tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx, int attempt)
{
    SSLContext *myCtx = (SSLContext *)ctx;

    sslDebugLog("%p attempt=%d\n", ctx, attempt);

    if(attempt) {
        myCtx->timeout_deadline = CFAbsoluteTimeGetCurrent()+((1<<(attempt-1))*myCtx->timeout_duration);
    } else {
        myCtx->timeout_deadline = 0; // cancel the timeout
    }
    return 0;
}
Esempio n. 11
0
static int
tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer *sessionData)
{
    SSLContext *myCtx = (SSLContext *)ctx;
    int err = errSSLSessionNotFound;

    SSLFreeBuffer(&myCtx->resumableSession);
    if(myCtx->cache) {
        err = tls_cache_load_session_data(myCtx->cache, &sessionKey, &myCtx->resumableSession);
    }
    sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx, sessionKey.length, sessionData->length, err);
    *sessionData = myCtx->resumableSession;

    return err;
}
Esempio n. 12
0
static void
tls_handshake_ready_callback(tls_handshake_ctx_t ctx, bool write, bool ready)
{
    SSLContext *myCtx = (SSLContext *)ctx;

    sslDebugLog("%p %s ready=%d\n", myCtx, write?"write":"read", ready);

    if(write) {
        myCtx->writeCipher_ready=ready?1:0;
    } else {
        myCtx->readCipher_ready=ready?1:0;
        if(ready) {
            SSLChangeHdskState(myCtx, SSL_HdskStateReady);
        } else {
            SSLChangeHdskState(myCtx, SSL_HdskStatePending);
        }
    }
}
Esempio n. 13
0
int
tls_handshake_request_renegotiation(tls_handshake_t filter)
{
    int err;

    if (filter->state != SSL_HdskStateServerReady)
    {
        sslDebugLog("Requesting renegotiation while handshake in progress...");
        return errSSLIllegalParam; // TODO: better error code for this case.
    }

    require_noerr((err=SSLResetFlight(filter)), errOut);
    filter->hdskMessageSeq=0;
    require_noerr((err=SSLPrepareAndQueueMessage(SSLEncodeServerHelloRequest, tls_record_type_Handshake, filter)), errOut);
    require_noerr((err=SSLSendFlight(filter)), errOut);

errOut:
    return err;
}
Esempio n. 14
0
/* (re)handshake */
int
tls_handshake_negotiate(tls_handshake_t filter, tls_buffer *peerID)
{
    assert(!filter->isServer);

    if ((filter->state != SSL_HdskStateClientReady) && (filter->state != SSL_HdskStateClientUninit))
    {
        sslDebugLog("Requesting renegotiation while handshake in progress...");
        return errSSLIllegalParam; // TODO: better error code for this case.
    }

    if(peerID) {
        check(filter->peerID.data==NULL); // Note sure that's illegal, but it's fishy
        filter->callbacks->load_session_data(filter->callback_ctx, *peerID, &filter->resumableSession);
        SSLFreeBuffer(&filter->peerID);
        SSLCopyBuffer(peerID, &filter->peerID);
    } else {
        SSLFreeBuffer(&filter->peerID);
    }
    return SSLAdvanceHandshake(SSL_HdskHelloRequest, filter);
}
Esempio n. 15
0
static int
tls_handshake_message_callback(tls_handshake_ctx_t ctx, tls_handshake_message_t event)
{
    SSLContext *myCtx = (SSLContext *)ctx;
    const tls_buffer *npn_data;
    const tls_buffer *alpn_data;
    int err = 0;

    sslDebugLog("%p, message = %d\n", ctx, event);
    
    switch(event) {
        case tls_handshake_message_certificate_request:
            assert(myCtx->protocolSide == kSSLClientSide);
            // Need to call this here, in case SetCertificate was already called.
            myCtx->clientCertState = kSSLClientCertRequested;
            myCtx->clientAuthTypes = tls_handshake_get_peer_acceptable_client_auth_type(myCtx->hdsk, &myCtx->numAuthTypes);
            if (myCtx->breakOnCertRequest && (myCtx->localCertArray==NULL)) {
                myCtx->signalCertRequest = true;
                err = errSSLClientCertRequested;
            }
            break;
        case tls_handshake_message_client_hello:
            myCtx->peerSigAlgs = tls_handshake_get_peer_signature_algorithms(myCtx->hdsk, &myCtx->numPeerSigAlgs);
            if (myCtx->breakOnClientHello) {
                err = errSSLClientHelloReceived;
            }
            break;
        case tls_handshake_message_server_hello:
            myCtx->serverHelloReceived = true;
            alpn_data = tls_handshake_get_peer_alpn_data(myCtx->hdsk);
            if(alpn_data) {
                myCtx->alpnFunc(myCtx, myCtx->alpnFuncInfo, alpn_data->data, alpn_data->length);
            } else {
                npn_data = tls_handshake_get_peer_npn_data(myCtx->hdsk);
                if(npn_data) {
                    myCtx->npnFunc(myCtx, myCtx->npnFuncInfo, npn_data->data, npn_data->length);
                }
            }
            myCtx->peerSigAlgs = tls_handshake_get_peer_signature_algorithms(myCtx->hdsk, &myCtx->numPeerSigAlgs);
            break;
        case tls_handshake_message_certificate:
            /* For clients, we only check the cert when we receive the ServerHelloDone message.
               For servers, we check the client's cert right here. For both we set the public key */
            err = tls_helper_set_peer_pubkey(myCtx->hdsk);
            if(!err && (myCtx->protocolSide == kSSLServerSide)) {
                err = tls_verify_peer_cert(myCtx);
            }
            break;
        case tls_handshake_message_server_hello_done:
            err = tls_verify_peer_cert(myCtx);
            break;
        case tls_handshake_message_NPN_encrypted_extension:
            npn_data = tls_handshake_get_peer_npn_data(myCtx->hdsk);
            if(npn_data)
                myCtx->npnFunc(myCtx, myCtx->npnFuncInfo, npn_data->data, npn_data->length);
            break;
        case tls_handshake_message_certificate_status:
            break;
        default:
            break;
    }

    return err;
}