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;
}
/* 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;
    }
}
/* 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;
}
/* 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;
}
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;
}
Exemple #6
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;
}
Exemple #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;
}
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;
}
uint8_t *sslAllocCopy(
	const uint8_t *src,
	size_t len)
{
	uint8_t *dst;
	
	dst = (uint8_t *)sslMalloc(len);
	if(dst == NULL) {
		return NULL;
	}
	memmove(dst, src, len);
	return dst;
}
/* 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;
}
/*
 * 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
}
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;
}
Exemple #13
0
/* Create an HMAC session */
static OSStatus HMAC_Alloc(
	const struct HMACReference	*hmac,
	SSLContext 					*ctx,
	const void					*keyPtr,
	unsigned					keyLen,
	HMACContextRef				*hmacCtxOut)		// RETURNED
{
	CCHmacAlgorithm	ccAlg;

	HMACContextRef hmacCtx = (HMACContextRef)sslMalloc(sizeof(struct HMACContext));

	if(hmacCtx == NULL) {
		return memFullErr;
	}
	hmacCtx->ctx = ctx;
	hmacCtx->hmac = hmac;

	switch(hmac->alg) {
		case HA_SHA384:
			ccAlg = kCCHmacAlgSHA384;
			hmacCtx->macSize = CC_SHA384_DIGEST_LENGTH;
			break;
		case HA_SHA256:
			ccAlg = kCCHmacAlgSHA256;
			hmacCtx->macSize = CC_SHA256_DIGEST_LENGTH;
			break;
		case HA_SHA1:
			ccAlg = kCCHmacAlgSHA1;
			hmacCtx->macSize = CC_SHA1_DIGEST_LENGTH;
			break;
		case HA_MD5:
			ccAlg = kCCHmacAlgMD5;
			hmacCtx->macSize = CC_MD5_DIGEST_LENGTH;
			break;
		default:
			ASSERT(0);
			return errSSLInternal;
	}

	/* create the template from which individual record MAC-ers are cloned */
	CCHmacInit(&hmacCtx->ccHmacTemplate, ccAlg, keyPtr, keyLen);
	*hmacCtxOut = hmacCtx;
	return noErr;
}
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;
}
Exemple #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;
}
static OSStatus
parseIncomingCerts(CFArrayRef			certs,
                   SSLCertificate       **destCertChain, /* &ctx->{localCertChain,encryptCertChain} */
                   tls_private_key_t    *sslPrivKey)	 /* &ctx->signingPrivKeyRef, etc. */
{
    OSStatus			ortn;
    CFIndex				ix, numCerts;
    SecIdentityRef 		identity;
    SSLCertificate      *certChain = NULL;	/* Retained */
    SecCertificateRef	leafCert = NULL;	/* Retained */
    SecKeyRef           privKey = NULL;	/* Retained */

    assert(destCertChain != NULL);		/* though its referent may be NULL */
    assert(sslPrivKey != NULL);

    if (certs == NULL) {
        sslErrorLog("parseIncomingCerts: NULL incoming cert array\n");
        ortn = errSSLBadCert;
        goto errOut;
    }
    numCerts = CFArrayGetCount(certs);
    if (numCerts == 0) {
        sslErrorLog("parseIncomingCerts: empty incoming cert array\n");
        ortn = errSSLBadCert;
        goto errOut;
    }

    certChain=sslMalloc(numCerts*sizeof(SSLCertificate));
    if (!certChain) {
        ortn = errSecAllocate;
        goto errOut;
    }

    /*
     * Certs[0] is an SecIdentityRef from which we extract subject cert,
     * privKey, pubKey.
     *
     * 1. ensure the first element is a SecIdentityRef.
     */
    identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
    if (identity == NULL) {
        sslErrorLog("parseIncomingCerts: bad cert array (1)\n");
        ortn = errSecParam;
        goto errOut;
    }
    if (CFGetTypeID(identity) != SecIdentityGetTypeID()) {
        sslErrorLog("parseIncomingCerts: bad cert array (2)\n");
        ortn = errSecParam;
        goto errOut;
    }

    /*
     * 2. Extract cert, keys and convert to local format.
     */
    ortn = SecIdentityCopyCertificate(identity, &leafCert);
    if (ortn) {
        sslErrorLog("parseIncomingCerts: bad cert array (3)\n");
        goto errOut;
    }

    /* Fetch private key from identity */
    ortn = SecIdentityCopyPrivateKey(identity, &privKey);
    if (ortn) {
        sslErrorLog("parseIncomingCerts: SecIdentityCopyPrivateKey err %d\n",
                    (int)ortn);
        goto errOut;
    }

    /* Convert the input array of SecIdentityRef at the start to an array of
     all certificates. */
    SSLCopyBufferFromData(SecCertificateGetBytePtr(leafCert), SecCertificateGetLength(leafCert), &certChain[0].derCert);
    certChain[0].next = NULL;

    for (ix = 1; ix < numCerts; ++ix) {
        SecCertificateRef intermediate =
        (SecCertificateRef)CFArrayGetValueAtIndex(certs, ix);
        if (intermediate == NULL) {
            sslErrorLog("parseIncomingCerts: bad cert array (5)\n");
            ortn = errSecParam;
            goto errOut;
        }
        if (CFGetTypeID(intermediate) != SecCertificateGetTypeID()) {
            sslErrorLog("parseIncomingCerts: bad cert array (6)\n");
            ortn = errSecParam;
            goto errOut;
        }

        SSLCopyBufferFromData(SecCertificateGetBytePtr(intermediate), SecCertificateGetLength(intermediate), &certChain[ix].derCert);
        certChain[ix].next = NULL;
        certChain[ix-1].next = &certChain[ix];

    }

    size_t size = SecKeyGetBlockSize(privKey);
    tls_private_key_desc_t desc;

    if(SecKeyGetAlgorithmId(privKey) == kSecRSAAlgorithmID) {
        desc.type = tls_private_key_type_rsa;
        desc.rsa.sign = mySSLPrivKeyRSA_sign;
        desc.rsa.decrypt = mySSLPrivKeyRSA_decrypt;
        desc.rsa.size = SecKeyGetBlockSize(privKey);
    } else if (SecKeyGetAlgorithmId(privKey) == kSecECDSAAlgorithmID) {
        desc.type = tls_private_key_type_ecdsa;
        desc.ecdsa.sign = mySSLPrivKeyECDSA_sign;
        desc.ecdsa.curve = SecECKeyGetNamedCurve(privKey);
#if TARGET_OS_IPHONE
        /* Compute signature size from key size */
        desc.ecdsa.size  = 8+2*size;
#else
        desc.ecdsa.size  = size;
#endif
    } else {
        ortn = errSecParam;
        goto errOut;
    }
    *sslPrivKey = tls_private_key_create(&desc, privKey, (tls_private_key_ctx_release)&CFRelease);
    if(*sslPrivKey)
        ortn = errSecSuccess;
    else
        ortn = errSecAllocate;
    
    /* SUCCESS */
errOut:
    CFReleaseSafe(leafCert);

    if (ortn) {
        free(certChain);
        CFReleaseSafe(privKey);
        *destCertChain = NULL;
    } else {
        *destCertChain = certChain;
    }
    
    return ortn;
}
/*
 * 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;
}
        .p = {
            .length = prime->length,
            .data = prime->data,
        },
        .g = {
            .length = generator->length,
            .data = generator->data,
        },
        .l = {
            .length = 0,
            .data = NULL,
        }
    };

    DERSize ioLen = DH_ENCODED_PARAM_SIZE(derParams.p.length);
    DERByte *der = sslMalloc(ioLen);
    // FIXME: What if this fails - we should probably not have a malloc here ?
    assert(der);
    ortn = (OSStatus)DEREncodeSequence(ASN1_CONSTR_SEQUENCE,
                                       &derParams,
                                       DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs,
                                       der,
                                       &ioLen);
    // This should never fail

    blob->length=ioLen;
    blob->data=der;

    return ortn;
}
Exemple #21
0
static void SessionCacheInit(void) {
    gSessionCache = sslMalloc(sizeof(SessionCache));
    gSessionCache->head = NULL;
    gSessionCache->mTimeToLive = SESSION_CACHE_TTL;
}