コード例 #1
0
/*
 * Given a SecCertificateRef cert, obtain its public key as a SSLPubKey.
 * Caller must sslFreePubKey and free the SSLPubKey itself.
 */
extern OSStatus sslCopyPeerPubKey(
	SSLContext 				*ctx,
	SSLPubKey               **pubKey)
{
    OSStatus status = noErr;

    check(pubKey);
    check(ctx->peerSecTrust);

    if (!ctx->enableCertVerify) {
        SecTrustResultType result;
        require_noerr(status = SecTrustEvaluate(ctx->peerSecTrust, &result),
            errOut);
	}

    SecKeyRef key = SecTrustCopyPublicKey(ctx->peerSecTrust);
    if (!key) {
		sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n",
			"SecTrustCopyPublicKey failed", (uintptr_t)ctx->peerSecTrust);
		return errSSLBadCert;
	}
    *pubKey = (SSLPubKey*)key;

errOut:
	if (status) {
		sslErrorLog("sslCopyPeerPubKey: error %d\n", status);
	}
	return status;
}
コード例 #2
0
ファイル: sslDecode.c プロジェクト: carriercomm/osx-2
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;
}
コード例 #3
0
/* common for sslv3 and tlsv1, except for the computeMac callout */
int SSLVerifyMac(uint8_t type,
                 SSLBuffer *data,
                 uint8_t *compareMAC,
                 struct SSLRecordInternalContext *ctx)
{
	int        err;
    uint8_t           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;

	check(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("SSLVerifyMac: Mac verify failure\n");
        return errSSLRecordProtocol;
    }
    return 0;
}
コード例 #4
0
/*
 * Verify a chain of DER-encoded certs.
 * First cert in a chain is root; this must also be present
 * in ctx->trustedCerts.
 *
 * If arePeerCerts is true, host name verification is enabled and we
 * save the resulting SecTrustRef in ctx->peerSecTrust. Otherwise
 * we're just validating our own certs; no host name checking and
 * peerSecTrust is transient.
 */
 OSStatus sslVerifyCertChain(
	SSLContext				*ctx,
	const SSLCertificate	*certChain,
	bool					arePeerCerts)
{
	OSStatus ortn = noErr;

    assert(certChain);

    /* No point checking our own certs, our clients can do that. */
    if (!arePeerCerts)
        return noErr;

    CertVerifyReturn cvrtn;
    /* @@@ Add real cert checking. */
    if (certChain->next) {
        DERItem subject, issuer;

        issuer.data = certChain->derCert.data;
        issuer.length = certChain->derCert.length;
        subject.data = certChain->next->derCert.data;
        subject.length = certChain->next->derCert.length;
        cvrtn = certVerify(&subject, &issuer);
        if (cvrtn != CVR_Success)
            ortn = errSSLBadCert;
    }
    else
    {
		sslErrorLog("***sslVerifyCertChain: only one cert in chain\n");
    }
	return ortn;
}
コード例 #5
0
int
tls_handshake_process(tls_handshake_t filter, const tls_buffer message, uint8_t contentType)
{
    int err;
    switch (contentType)
    {
        case tls_record_type_Handshake:
            sslLogRxProtocolDebug("Handshake");
            err = SSLProcessHandshakeRecord(message, filter);
            break;
        case tls_record_type_Alert:
            sslLogRxProtocolDebug("Alert");
            err = SSLProcessAlert(message, filter);
            break;
        case tls_record_type_ChangeCipher:
            sslLogRxProtocolDebug("ChangeCipher");
            err = SSLProcessChangeCipherSpec(message, filter);
            break;
        case tls_record_type_SSL2:
            sslLogRxProtocolDebug("SSL2");
            err = SSLProcessSSL2Message(message, filter);
            break;
        default:
            sslLogRxProtocolDebug("Not a supported protocol message");
            return errSSLProtocol;
    }

    if(err==errSSLUnexpectedRecord)
        err=DTLSRetransmit(filter);

    if(err)
        sslErrorLog("Error processing a message (ct=%d, err=%d)", contentType, err);

    return err;
}
コード例 #6
0
OSStatus sslRawVerify(
	SSLContext			*ctx,
	SSLPubKey           *pubKey,
	const uint8_t       *plainText,
	size_t              plainTextLen,
	const uint8_t       *sig,
	size_t              sigLen)         // available
{
#if 0
	RSAStatus rsaStatus;

	rsaStatus = RSA_SigVerify(&pubKey->rsaKey,
		RP_PKCS1,
		plainText,
		plainTextLen,
		sig,
		sigLen);

	return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
#else
	OSStatus status = SecKeyRawVerify(SECKEYREF(pubKey), kSecPaddingPKCS1,
        plainText, plainTextLen, sig, sigLen);

	if (status) {
		sslErrorLog("sslRawVerify: SecKeyRawVerify failed (error %d)\n", status);
	}

	return status;
#endif
}
コード例 #7
0
/* TLS 1.2 RSA signature */
OSStatus sslRsaSign(
                    SSLContext			*ctx,
                    SSLPrivKey          *privKey,
                    const SecAsn1AlgId  *algId,
                    const uint8_t       *plainText,
                    size_t              plainTextLen,
                    uint8_t				*sig,			// mallocd by caller; RETURNED
                    size_t              sigLen,         // available
                    size_t              *actualBytes)   // RETURNED
{
	size_t inOutSigLen = sigLen;

	assert(actualBytes != NULL);

    OSStatus status = SecKeySignDigest(SECKEYREF(privKey), algId,
                                    plainText, plainTextLen, sig, &inOutSigLen);

	if (status) {
		sslErrorLog("sslRsaSign: SecKeySignDigest failed (error %d)\n", status);
	}

    /* Since the KeyExchange already allocated modulus size bytes we'll
     use all of them.  SecureTransport has always sent that many bytes,
     so we're not going to deviate, to avoid interoperability issues. */
    if (!status && (inOutSigLen < sigLen)) {
        size_t offset = sigLen - inOutSigLen;
        memmove(sig + offset, sig, inOutSigLen);
        memset(sig, 0, offset);
        inOutSigLen = sigLen;
    }

	*actualBytes = inOutSigLen;
	return status;
}
コード例 #8
0
static OSStatus errorTranslate(int recordErr)
{
    switch(recordErr) {
        case errSecSuccess:
            return errSecSuccess;
        case errSSLRecordInternal:
            return errSSLInternal;
        case errSSLRecordWouldBlock:
            return errSSLWouldBlock;
        case errSSLRecordProtocol:
            return errSSLProtocol;
        case errSSLRecordNegotiation:
            return errSSLNegotiation;
        case errSSLRecordClosedAbort:
            return errSSLClosedAbort;
        case errSSLRecordConnectionRefused:
            return errSSLConnectionRefused;
        case errSSLRecordDecryptionFail:
            return errSSLDecryptionFail;
        case errSSLRecordBadRecordMac:
            return errSSLBadRecordMac;
        case errSSLRecordRecordOverflow:
            return errSSLRecordOverflow;
        case errSSLRecordUnexpectedRecord:
            return errSSLUnexpectedRecord;
        default:
            sslErrorLog("unknown error code returned in sslErrorTranslate: %d\n", recordErr);
            return recordErr;
    }
}
コード例 #9
0
/* 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;
}
コード例 #10
0
int
tls_record_decrypt(tls_record_t ctx,
                          const tls_buffer input,
                          tls_buffer *output,
                          uint8_t *contentType)
{
    int        err;
    tls_buffer       cipherFragment;
    uint8_t         *charPtr;
    uint64_t        seqNum;
    uint8_t         ct;
    charPtr=input.data;

    check(input.length>=header_size(ctx));

    if(input.length<header_size(ctx))
        return errSSLRecordParam;

    ct = *charPtr++;
#if 0 // We dont actually check the record protocol version
    tls_protocol_version pv;
    pv = SSLDecodeInt(charPtr, 2);
#endif
    charPtr+=2;
    if(ctx->isDTLS) {
        seqNum = SSLDecodeUInt64(charPtr, 8); charPtr+=8;
    }

    cipherFragment.length = SSLDecodeInt(charPtr, 2); charPtr+=2;
    cipherFragment.data = charPtr;

#if 0 // This is too strict for the record layer.
    if (ct < tls_record_type_V3_Smallest ||
        ct > tls_record_type_V3_Largest)
        return errSSLRecordProtocol;

    if ((ctx->negProtocolVersion != tls_protocol_version_Undertermined) &&
        (pv != ctx->negProtocolVersion)) {
        sslErrorLog("invalid record protocol version, expected = %04x, received = %04x", ctx->negProtocolVersion, pv);
        return errSSLRecordProtocol; // Invalid record version ?
    }
#endif

    check(input.length>=header_size(ctx)+cipherFragment.length);

    if(input.length<header_size(ctx)+cipherFragment.length) {
        return errSSLRecordParam; // input buffer not enough data
    }

    if(ctx->isDTLS)
    {
        /* if the epoch of the record is different of current read cipher, just drop it */
        if((seqNum>>48)!=(ctx->readCipher.sequenceNum>>48)) {
            return errSSLRecordUnexpectedRecord;
        } else {
            ctx->readCipher.sequenceNum=seqNum;
        }
    }
コード例 #11
0
ファイル: sslBER.c プロジェクト: Apple-FOSS-Mirror/Security
/*
 * Given an ECDSA public key in X509 format, extract the raw public key
 * bits in ECPOint format.
 */
OSStatus sslEcdsaPubKeyBits(
	CSSM_KEY_PTR	pubKey,
	SSLBuffer		*pubBits)		/* data mallocd and RETURNED */
{
	SecAsn1CoderRef coder = NULL;
	CSSM_X509_SUBJECT_PUBLIC_KEY_INFO subjPubKeyInfo;
	OSStatus ortn = noErr;

	CSSM_KEYHEADER *hdr = &pubKey->KeyHeader;
	if(hdr->AlgorithmId != CSSM_ALGID_ECDSA) {
	   sslErrorLog("sslEcdsaPubKeyBits: bad peer key algorithm\n");
	   return errSSLProtocol;
	}
	if(hdr->BlobType != CSSM_KEYBLOB_RAW) {
		/* No can do - this must be raw format, it came from the CL */
	   sslErrorLog("sslEcdsaPubKeyBits: bad peer key algorithm\n");
	   return errSSLProtocol;
	}
	if(hdr->Format != CSSM_KEYBLOB_RAW_FORMAT_X509) {
	   sslErrorLog("sslEcdsaPubKeyBits: bad peer key format\n");
	   return errSSLProtocol;
	}

	/* KeyData is an encoded CSSM_X509_SUBJECT_PUBLIC_KEY_INFO */
	ortn = SecAsn1CoderCreate(&coder);
	if(ortn) {
		return errSSLInternal;
	}
	/* subsequent errors to errOut: */

	memset(&subjPubKeyInfo, 0, sizeof(subjPubKeyInfo));
	ortn = SecAsn1DecodeData(coder, &pubKey->KeyData, kSecAsn1SubjectPublicKeyInfoTemplate,
		&subjPubKeyInfo);
	if(ortn) {
		printf("sslEcdsaPubKeyBits: error decoding public key\n");
		goto errOut;
	}
	/* that key data is a BITSTRING */
	ortn = SSLCopyBufferFromData(subjPubKeyInfo.subjectPublicKey.Data,
		subjPubKeyInfo.subjectPublicKey.Length >> 3, pubBits);
errOut:
	SecAsn1CoderRelease(coder);
	return ortn;
}
コード例 #12
0
ファイル: sslCert.c プロジェクト: darlinghq/darling-coretls
int
SSLProcessCertificateStatus(tls_buffer message, tls_handshake_t ctx)
{
    uint8_t status_type;
    uint8_t *p = message.data;
    assert(!ctx->isServer);

    if (message.length < 1) {
        sslErrorLog("SSLProcessCertificateStatus: message length decode error (1)\n");
        return errSSLProtocol;
    }

    status_type = *p++;

    if(status_type!=SSL_CST_Ocsp) {
        return noErr;
    }

    if (message.length < 3) {
        sslErrorLog("SSLProcessCertificateStatus: message length decode error (2)\n");
        return errSSLProtocol;
    }

    size_t OCSPResponseLen = SSLDecodeSize(p, 3); p+=3;

    if(OCSPResponseLen==0) {
        sslErrorLog("SSLProcessCertificateStatus: message length decode error (3)\n");
        return errSSLProtocol;
    }

    if(OCSPResponseLen+4 != message.length) {
        sslErrorLog("SSLProcessCertificateStatus: message length decode error (4)\n");
        return errSSLProtocol;
    }

    ctx->ocsp_response_received = true;

    SSLFreeBuffer(&ctx->ocsp_response);
    return SSLCopyBufferFromData(p, OCSPResponseLen, &ctx->ocsp_response);
}
コード例 #13
0
ファイル: sslBER.c プロジェクト: Apple-FOSS-Mirror/Security
/*
 * Given a DER encoded DHParameterBlock, extract the prime and generator.
 * modulus and public exponent.
 * This will work with either PKCS-1 encoded DHParameterBlock or
 * openssl-style DHParameter.
 */
OSStatus sslDecodeDhParams(
	const SSLBuffer	*blob,			/* PKCS-1 encoded */
	SSLBuffer		*prime,			/* data mallocd and RETURNED */
	SSLBuffer		*generator)		/* data mallocd and RETURNED */
{
    SECStatus rv;
	OSStatus srtn;
	NSS_DHParameterBlock paramBlock = {};
    PLArenaPool *pool;

	assert(blob != NULL);
	assert(prime != NULL);
	assert(generator != NULL);

    pool = PORT_NewArena(CHUNKSIZE_DEF);
	/*
	 * Since the common case here is to decode a parameter block coming
	 * over the wire, which is in openssl format, let's try that format first.
	 */
    rv = SEC_ASN1Decode(pool, &paramBlock.params,
        kSecAsn1DHParameterTemplate, (const char *)blob->data, blob->length);
    if (rv != SECSuccess) {
		/*
		 * OK, that failed when trying as a CDSA_formatted parameter
		 * block DHParameterBlock). Openssl uses a subset of that,
		 * a DHParameter. Try that instead.
		 */
		memset(&paramBlock, 0, sizeof(paramBlock));
        rv = SEC_ASN1Decode(pool, &paramBlock,
            kSecAsn1DHParameterBlockTemplate,
            (const char *)blob->data, blob->length);
	}

    if (rv != SECSuccess) {
        /* Ah well, we tried. */
        sslErrorLog("sslDecodeDhParams: both CDSA and openssl format"
            "failed\n");
        srtn = errSSLCrypto;
    }
    else {
        /* copy out components */
        srtn = SSLCopyBufferFromData(paramBlock.params.prime.Data,
            paramBlock.params.prime.Length, prime);
        if(!srtn) {
            srtn = SSLCopyBufferFromData(paramBlock.params.base.Data,
                paramBlock.params.base.Length, generator);
        }
    }

    PORT_FreeArena(pool, PR_TRUE);
    return srtn;
}
コード例 #14
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;
}
コード例 #15
0
int
SSLReallocBuffer(SSLBuffer *buf, size_t newSize)
{   
	buf->data = (uint8_t *)sslRealloc(buf->data, buf->length, newSize);
	if(buf->data == NULL) {
        sslErrorLog("SSLReallocBuffer: NULL buf!\n");
        check(0);
		buf->length = 0;
		return -1;
	}
	buf->length = newSize;
	return 0;
}
コード例 #16
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
}
コード例 #17
0
int SSLCopyBufferFromData(
	const void *src,
	size_t len,
	SSLBuffer *dst)		// data mallocd and returned 
{   
	dst->data = sslAllocCopy((const uint8_t *)src, len);
	if(dst->data == NULL) {
        sslErrorLog("SSLCopyBufferFromData: NULL buf!\n");
        check(0);
		return -1;
	}
    dst->length = len;
    return 0;
}
コード例 #18
0
int SSLAllocBuffer(
	SSLBuffer *buf,
	size_t length)
{
	buf->data = (uint8_t *)sslMalloc(length);
	if(buf->data == NULL) {
        sslErrorLog("SSLAllocBuffer: NULL buf!\n");
        check(0);
		buf->length = 0;
		return -1;
	}
    buf->length = length;
    return 0;
}
コード例 #19
0
/* SSLWriteRecord
 *  Attempt to encrypt and queue an SSL record.
 */
OSStatus
SSLWriteRecord(SSLRecord rec, SSLContext *ctx)
{
    OSStatus    err;

    err=errorTranslate(ctx->recFuncs->write(ctx->recCtx, rec));

    switch(err) {
        case errSecSuccess:
            break;
        default:
            sslErrorLog("unexpected error code returned in SSLWriteRecord: %d\n", (int)err);
            break;
    }

    return err;
}
コード例 #20
0
/* SSLReadRecord
 *  Attempt to read & decrypt an SSL record.
 *  Record content should be freed using SSLFreeRecord
 */
OSStatus
SSLReadRecord(SSLRecord *rec, SSLContext *ctx)
{   OSStatus        err;

    err=errorTranslate(ctx->recFuncs->read(ctx->recCtx, rec));

    switch(err) {
        case errSecSuccess:
        case errSSLWouldBlock:
            break;
        case errSSLUnexpectedRecord:
            DTLSRetransmit(ctx);
            break;
        case errSSLDecryptionFail:
        case errSSLBadRecordMac:
            /* We never send a Decryption Failed alert, instead we send the BadRecordMac alert */
            /* This is TLS 1.1 compliant - Do it for all protocols versions. */
            /* Except for DTLS where we do not send any alert. */
            if(ctx->isDTLS) {
                /* This will ensure we try to read again before returning to the caller
                   We do NOT want to use errSSLWouldBlock here, as this should only indicate
                   the IO read callback status */
                err=errSSLUnexpectedRecord;
            } else {
                SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
            }
            break;
        case errSSLInternal:
            SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
            break;
        case errSSLRecordOverflow:
            SSLFatalSessionAlert(SSL_AlertRecordOverflow, ctx);
            break;
        case errSSLClosedAbort:
        case errSSLConnectionRefused:
            SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
            break;
        default:
            sslErrorLog("unknown error code returned in SSLReadRecord: %d\n", (int)err);
            SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
            break;
    }

    return err;
}
コード例 #21
0
/* TLS 1.2 RSA verify */
OSStatus sslRsaVerify(
                      SSLContext		  *ctx,
                      SSLPubKey           *pubKey,
                      const SecAsn1AlgId  *algId,
                      const uint8_t       *plainText,
                      size_t              plainTextLen,
                      const uint8_t       *sig,
                      size_t              sigLen)         // available
{
	OSStatus status = SecKeyVerifyDigest(SECKEYREF(pubKey), algId,
                           plainText, plainTextLen, sig, sigLen);

	if (status) {
		sslErrorLog("sslRsaVerify: SecKeyVerifyDigest failed (error %d)\n", status);
	}

	return status;
}
コード例 #22
0
OSStatus sslRsaDecrypt(
	SSLContext			*ctx,
	SSLPrivKey			*privKey,
	const uint32_t		padding,
	const uint8_t       *cipherText,
	size_t              cipherTextLen,
	uint8_t				*plainText,			// mallocd by caller; RETURNED
	size_t              plainTextLen,		// available
	size_t              *actualBytes) 		// RETURNED
{
#if 0
	gi_uint16 giPlainTextLen = plainTextLen;
	RSAStatus rsaStatus;

	assert(actualBytes != NULL);

	rsaStatus = RSA_Decrypt(&privKey->rsaKey,
		RP_PKCS1,
		cipherText,
		cipherTextLen,
		plainText,
		&giPlainTextLen);
	*actualBytes = giPlainTextLen;

	return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
#else
	size_t ptlen = plainTextLen;

	assert(actualBytes != NULL);

    OSStatus status = SecKeyDecrypt(SECKEYREF(privKey), padding,
        cipherText, cipherTextLen, plainText, &ptlen);
	*actualBytes = ptlen;

    if (status) {
        sslErrorLog("sslRsaDecrypt: SecKeyDecrypt failed (error %d)\n", status);
	}

	return status;
#endif
}
コード例 #23
0
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;
}
コード例 #24
0
static const struct ccdigest_info *sslCipherSuiteGetDigestInfo(uint16_t selectedCipher)
{
    HMAC_Algs alg = sslCipherSuiteGetMacAlgorithm(selectedCipher);

    switch (alg) {
        case HA_Null:
            return &null_di;
        case HA_MD5:
            return ccmd5_di();
        case HA_SHA1:
            return ccsha1_di();
        case HA_SHA256:
            return ccsha256_di();
        case HA_SHA384:
            return ccsha384_di();
        default:
            sslErrorLog("Invalid hashAlgorithm %d", alg);
            check(0);
            return NULL;
    }
}
コード例 #25
0
static const HashHmacReference *sslCipherSuiteGetHashHmacReference(uint16_t selectedCipher)
{
    HMAC_Algs alg = sslCipherSuiteGetMacAlgorithm(selectedCipher);

    switch (alg) {
        case HA_Null:
            return &HashHmacNull;
        case HA_MD5:
            return &HashHmacMD5;
        case HA_SHA1:
            return &HashHmacSHA1;
        case HA_SHA256:
            return &HashHmacSHA256;
        case HA_SHA384:
            return &HashHmacSHA384;
        default:
            sslErrorLog("Invalid hashAlgorithm %d", alg);
            check(0);
            return &HashHmacNull;
    }
}
コード例 #26
0
ファイル: sslKeyExchange.c プロジェクト: pg314/goto-fail
OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
                                 uint8_t *signature, UInt16 signatureLen)
{
        OSStatus err;
        uint8_t buf[SSL_MAX_DIGEST_LEN];
        const HashReference *hash;

        hash = isRsa ? &SSLHashMD5SHA1 : &SSLHashSHA1;

        SSLCalculateServerKeyExchangeHash(hash, ctx, signedParams, buf);

	err = sslRawVerify(ctx,
                           ctx->peerPubKey,
                           buf,
                           hash->digestSize,
                           signature,
                           signatureLen);
	if (err) {
		sslErrorLog("SSLVerifySignedServerKeyExchange: sslRawVerify "
                            "returned %d\n", (int)err);
	}
        return err;
}
コード例 #27
0
ファイル: sslCert.c プロジェクト: darlinghq/darling-coretls
int
SSLProcessCertificateVerify(tls_buffer message, tls_handshake_t ctx)
{   int        err;
    UInt8           hashData[SSL_MAX_DIGEST_LEN];
    size_t          signatureLen;
    tls_buffer       hashDataBuf;
    uint8_t         *charPtr = message.data;
	uint8_t         *endCp = charPtr + message.length;

    tls_signature_and_hash_algorithm    sigAlg = {0,};

    if (sslVersionIsLikeTls12(ctx)) {
        /* Parse the algorithm field added in TLS1.2 */
        if((charPtr+2) > endCp) {
            sslErrorLog("SSLProcessCertificateVerify: msg len error 1\n");
            return errSSLProtocol;
        }
        sigAlg.hash = *charPtr++;
        sigAlg.signature = *charPtr++;
    }

    if ((charPtr + 2) > endCp) {
    	sslErrorLog("SSLProcessCertificateVerify: msg len error\n");
        return errSSLProtocol;
    }

    signatureLen = SSLDecodeSize(charPtr, 2);
    charPtr += 2;
    if ((charPtr + signatureLen) > endCp) {
    	sslErrorLog("SSLProcessCertificateVerify: sig len error 1\n");
        return errSSLProtocol;
    }

    hashDataBuf.data = hashData;
    hashDataBuf.length = SSL_MAX_DIGEST_LEN;

	assert(ctx->sslTslCalls != NULL);
    if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
        goto fail;

    if (sslVersionIsLikeTls12(ctx))
    {
        if(sigAlg.signature==tls_signature_algorithm_RSA) {
            err = sslRsaVerify(&ctx->peerPubKey,
                               sigAlg.hash,
                               hashData,
                               hashDataBuf.length,
                               charPtr,
                               signatureLen);
        } else {
            err = sslRawVerify(&ctx->peerPubKey,
                               hashData,
                               hashDataBuf.length,
                               charPtr,
                               signatureLen);
        }
    } else {
        /* sslRawVerify does the decrypt & compare for us in one shot. */
        err = sslRawVerify(&ctx->peerPubKey,
            hashData,				// data to verify
            hashDataBuf.length,
            charPtr, 		// signature
            signatureLen);
    }

    if(err) {
		SSLFatalSessionAlert(SSL_AlertDecryptError, ctx);
		goto fail;
	}
    err = errSSLSuccess;

fail:
    return err;
}
コード例 #28
0
ファイル: sslCert.c プロジェクト: darlinghq/darling-coretls
int
SSLEncodeCertificateVerify(tls_buffer *certVerify, tls_handshake_t ctx)
{   int        err;
    UInt8           hashData[SSL_MAX_DIGEST_LEN];
    tls_buffer       hashDataBuf;
    size_t          len;
    size_t		    outputLen;
    UInt8           *charPtr;
    int             head;
    size_t          maxSigLen;

    certVerify->data = 0;
    hashDataBuf.data = hashData;
    hashDataBuf.length = SSL_MAX_DIGEST_LEN;


	assert(ctx->signingPrivKeyRef != NULL);
    err = sslGetMaxSigSize(ctx->signingPrivKeyRef, &maxSigLen);
    if(err) {
        goto fail;
    }

    tls_signature_and_hash_algorithm sigAlg = {0,};

	switch(ctx->signingPrivKeyRef->desc.type) {
        case tls_private_key_type_rsa:
            sigAlg.signature = tls_signature_algorithm_RSA;
            break;
        case tls_private_key_type_ecdsa:
            sigAlg.signature = tls_signature_algorithm_ECDSA;
            if (ctx->negProtocolVersion <= tls_protocol_version_SSL_3) {
                return errSSLInternal;
            }
			break;
		default:
			/* shouldn't be here */
			assert(0);
			return errSSLInternal;
	}

	assert(ctx->negProtocolVersion >= tls_protocol_version_SSL_3);
    head = SSLHandshakeHeaderSize(ctx);

    outputLen = maxSigLen + head + 2;

    // Note: this is only used for TLS 1.2
    if (sslVersionIsLikeTls12(ctx)) {
        err=FindCertSigAlg(ctx, &sigAlg);
        if(err)
            goto fail;
        outputLen += 2;
        ctx->certSigAlg = sigAlg; // Save for metrics reporting.
    }

    assert(ctx->sslTslCalls != NULL);
    if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
        goto fail;

    if ((err = SSLAllocBuffer(certVerify, outputLen)) != 0)
        goto fail;

    /* Sign now to get the actual length */
    charPtr = certVerify->data+head;

    if (sslVersionIsLikeTls12(ctx))
    {
        *charPtr++ = sigAlg.hash;
        *charPtr++ = sigAlg.signature;

        switch (sigAlg.hash) {
            case tls_hash_algorithm_SHA512:
            case tls_hash_algorithm_SHA384:
            case tls_hash_algorithm_SHA256:
            case tls_hash_algorithm_SHA1:
                break;
            default:
				sslErrorLog("SSLEncodeCertificateVerify: unsupported signature hash algorithm (%d)\n",
					sigAlg.hash);
                assert(0);          // if you get here, something is wrong in FindCertSigAlg
                err=errSSLInternal;
                goto fail;
        }

        if (sigAlg.signature == tls_signature_algorithm_RSA) {
            err = sslRsaSign(ctx->signingPrivKeyRef,
                             sigAlg.hash,
                             hashData,
                             hashDataBuf.length,
                             charPtr+2,
                             maxSigLen,
                             &outputLen);
        } else {
            err = sslEcdsaSign(ctx->signingPrivKeyRef,
                             hashData,
                             hashDataBuf.length,
                             charPtr+2,
                             maxSigLen,
                             &outputLen);
        }
        len=outputLen+2+2;
    } else {
        err = sslRawSign(ctx->signingPrivKeyRef,
            hashData,						// data to sign
            hashDataBuf.length,				// Data to sign size
            charPtr+2,	// signature destination
            maxSigLen,							// we mallocd len+head+2
            &outputLen);
        len = outputLen+2;
    }
	if(err) {
		sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", (int)err);
		goto fail;
	}
    // At this point:
    //  len = message length
    //  outputlen = sig length
	certVerify->length = len + head;

    /* charPtr point at the len field here */
    SSLEncodeSize(charPtr, outputLen, 2);

    SSLEncodeHandshakeHeader(ctx, certVerify, SSL_HdskCertVerify, len);

    err = errSSLSuccess;

fail:

    return err;
}
コード例 #29
0
ファイル: sslCert.c プロジェクト: darlinghq/darling-coretls
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;
}
コード例 #30
0
ファイル: sslCert.c プロジェクト: darlinghq/darling-coretls
int
SSLProcessCertificate(tls_buffer message, tls_handshake_t ctx)
{
    size_t          listLen;
    UInt8           *p;
    int        err = 0;
    SSLCertificate *certChain;

    if (message.length < 3) {
        sslErrorLog("SSLProcessCertificate: message length decode error\n");
        return errSSLProtocol;
    }

    p = message.data;
    listLen = SSLDecodeInt(p,3);
    p += 3;
    if (listLen + 3 != message.length) {
    	sslErrorLog("SSLProcessCertificate: length decode error 1\n");
        return errSSLProtocol;
    }

    // Note: An empty certificate list (listLen==0) is allowed by the TLS RFC,
    // but empty certificates (certLen==0) are not. Section 7.4.2 in RFC 5246
    // defines the message syntax as such:
    //
    //  opaque ASN.1Cert<1..2^24-1>;
    //
    //  struct {
    //        ASN.1Cert certificate_list<0..2^24-1>;
    //  } Certificate;
    //
    // Note the difference between <1..2^24-1> and <0..2^24-1>
    //

    if((err = SSLDecodeBufferList(p, listLen, 3, (tls_buffer_list_t **)&certChain))) {
        return err;
    }
    p+=listLen;

    /* Do not accept a different server cert during renegotiation unless allowed */
    if(!ctx->allowServerIdentityChange && ctx->peerCert && !CertificateChainEqual(ctx->peerCert, certChain)) {
        sslErrorLog("Illegal server identity change during renegotiation\n");
        SSLFreeCertificates(certChain);
        return errSSLProtocol;
    }

    if (ctx->peerCert == NULL && __ssl_debug_enabled("sslLogNegotiateDebug")) {
        debug_log_chain("sslLogNegotiateDebug", certChain);
    }

    /* Free certs if they already exist */
    SSLFreeCertificates(ctx->peerCert);
    ctx->peerCert=certChain;

    assert(p == message.data + message.length);

    /* Don't fail here if peerCert is NULL.
       An empty Certificate message is valid in some cases.
       The rest of the stack will handle it. */

    return err;
}