/* 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; }
/* 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; }