Ejemplo n.º 1
0
/*
 * Get algorithm id for a SSLPrivKey object.
 */
CFIndex sslPrivKeyGetAlgorithmID(SecKeyRef privKey)
{
#if TARGET_OS_IPHONE
	return SecKeyGetAlgorithmID(privKey);
#else
	return SecKeyGetAlgorithmId(privKey);
#endif
}
Ejemplo n.º 2
0
/*
 * Get algorithm id for a SSLPrivKey object.
 */
CFIndex sslPrivKeyGetAlgorithmID(SSLPrivKey *privKey)
{
#if TARGET_OS_IOS
	return SecKeyGetAlgorithmID(SECKEYREF(privKey));
#else
	return SecKeyGetAlgorithmId(SECKEYREF(privKey));
#endif
}
Ejemplo n.º 3
0
/* Extract the pubkey from a cert chain, and send it to the tls_handshake context */
static int tls_set_peer_pubkey(tls_handshake_t hdsk, const SSLCertificate *certchain)
{
    int err;
    CFIndex algId;
    SecKeyRef pubkey = NULL;
    CFDataRef modulus = NULL;
    CFDataRef exponent = NULL;
    CFDataRef ecpubdata = NULL;

#if 0
    {   /* dump certs */
        int i=0;
        int j;
        const SSLCertificate *tmp = certchain;
        while(tmp) {
            printf("cert%d[] = {", i);
            for(j=0; j<tmp->derCert.length; j++) {
                if((j&0xf)==0)
                    printf("\n");
                printf("0x%02x, ", tmp->derCert.data[j]);
            }
            printf("}\n");
            tmp=tmp->next;
            i++;
        }
    }
#endif

    require_noerr((err=sslCopyPeerPubKey(certchain, &pubkey)), errOut);

#if TARGET_OS_IPHONE
    algId = SecKeyGetAlgorithmID(pubkey);
#else
    algId = SecKeyGetAlgorithmId(pubkey);
#endif

    err = errSSLCrypto;

    switch(algId) {
    case kSecRSAAlgorithmID:
    {
        require((modulus = SecKeyCopyModulus(pubkey)), errOut);
        require((exponent = SecKeyCopyExponent(pubkey)), errOut);

        tls_buffer mod;
        tls_buffer exp;

        mod.data = (uint8_t *)CFDataGetBytePtr(modulus);
        mod.length = CFDataGetLength(modulus);

        exp.data = (uint8_t *)CFDataGetBytePtr(exponent);
        exp.length = CFDataGetLength(exponent);

        err = tls_handshake_set_peer_rsa_public_key(hdsk, &mod, &exp);
        break;
    }
    case kSecECDSAAlgorithmID:
    {
        tls_named_curve curve = SecECKeyGetNamedCurve(pubkey);
        require((ecpubdata = SecECKeyCopyPublicBits(pubkey)), errOut);

        tls_buffer pubdata;
        pubdata.data = (uint8_t *)CFDataGetBytePtr(ecpubdata);
        pubdata.length = CFDataGetLength(ecpubdata);

        err = tls_handshake_set_peer_ec_public_key(hdsk, curve, &pubdata);

        break;
    }
    default:
        break;
    }

errOut:
    CFReleaseSafe(pubkey);
    CFReleaseSafe(modulus);
    CFReleaseSafe(exponent);
    CFReleaseSafe(ecpubdata);

    return err;
}
Ejemplo n.º 4
0
/* Extract the pubkey from a cert chain, and send it to the tls_handshake context */
int tls_set_encrypt_pubkey(tls_handshake_t hdsk, const SSLCertificate *certchain)
{
    int err;
    CFIndex algId;
    SecTrustRef trustRef = NULL;
    SecKeyRef pubkey = NULL;
    CFDataRef modulus = NULL;
    CFDataRef exponent = NULL;

#if 0
    { /* dump certs */
        int i=0;
        int j;
        const SSLCertificate *tmp = certchain;
        while(tmp) {
            printf("cert%d[] = {", i);
            for(j=0; j<tmp->derCert.length; j++) {
                if((j&0xf)==0)
                    printf("\n");
                printf("0x%02x, ", tmp->derCert.data[j]);
            }
            printf("}\n");
            tmp=tmp->next;
            i++;
        }
    }
#endif

    require_noerr((err=tls_create_trust_from_certs(certchain, &trustRef)), errOut);
    require_action((pubkey = SecTrustCopyPublicKey(trustRef)), errOut, err=-9808); // errSSLBadCert

#if TARGET_OS_IPHONE
    algId = SecKeyGetAlgorithmID(pubkey);
#else
    algId = SecKeyGetAlgorithmId(pubkey);
#endif

    err = -9809; //errSSLCrypto;

    switch(algId) {
        case kSecRSAAlgorithmID:
        {
            require((modulus = SecKeyCopyModulus(pubkey)), errOut);
            require((exponent = SecKeyCopyExponent(pubkey)), errOut);

            tls_buffer mod;
            tls_buffer exp;

            mod.data = (uint8_t *)CFDataGetBytePtr(modulus);
            mod.length = CFDataGetLength(modulus);

            exp.data = (uint8_t *)CFDataGetBytePtr(exponent);
            exp.length = CFDataGetLength(exponent);

            err = tls_handshake_set_encrypt_rsa_public_key(hdsk, &mod, &exp);
            break;
        }
        default:
            break;
    }

errOut:
    CFReleaseSafe(trustRef);
    CFReleaseSafe(pubkey);
    CFReleaseSafe(modulus);
    CFReleaseSafe(exponent);

    return err;
}
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;
}