size_t SDMMD__ServiceReceiveBytesSSL(SocketConnection handle, void *buffer, int length) { int received = 0, receivedTotal = 0; if (handle.socket.ssl != NULL) { do { ERR_clear_error(); // Try to read up to length received = SSL_read(handle.socket.ssl, &buffer[receivedTotal], length - receivedTotal); if (received <= 0) { // Read failed, check if theres an SSLreceived error int ret = SSL_get_error(handle.socket.ssl, received); char *ssl_error = SDMMD_ssl_strerror(handle.socket.ssl, received); printf("SSL_read error: (%x) (%s)\n", ret, ssl_error); break; } // Move ahead length receivedTotal += received; } while (receivedTotal < length); } else { printf("%s: Invalid SSL Socket!\n", __PRETTY_FUNCTION__); } return receivedTotal; }
SSL* SDMMD_lockssl_handshake(SDMMD_lockdown_conn *lockdown_conn, CFTypeRef hostCert, CFTypeRef deviceCert, CFTypeRef hostPrivKey, uint32_t num) { SSL *ssl = NULL; SSL_CTX *sslCTX = NULL; sdmmd_return_t result = 0x0; BIO_METHOD *bioMethod = BIO_s_socket(); BIO *bioSocket = BIO_new(bioMethod); if (bioSocket) { BIO_set_fd(bioSocket, lockdown_conn->connection, 0); X509 *cert = SDMMD__decode_certificate(hostCert); if (cert == 0) { printf("_create_ssl_context: Could not certificate.\n"); } RSA *rsa = NULL; BIO *dataBIO = SDMMD__create_bio_from_data(hostPrivKey); if (dataBIO == 0) { printf("_create_ssl_context: Could not decode host private key.\n"); if (cert) { X509_free(cert); result = 0x0; } } else { PEM_read_bio_RSAPrivateKey(dataBIO, &rsa, 0x0, 0x0); BIO_free(dataBIO); if (rsa) { if (hostCert) { sslCTX = SSL_CTX_new(SSLv3_method()); if (sslCTX) { result = SSL_CTX_use_certificate(sslCTX, cert); if (result == 0) printf("_create_ssl_context: Could not set certificate.\n"); result = SSL_CTX_use_RSAPrivateKey(sslCTX, rsa); if (result == 0) printf("_create_ssl_context: Could not set private key.\n"); } else { printf("_create_ssl_context: Could not create SSLv3 context.\n"); } } RSA_free(rsa); if (cert) X509_free(cert); if (sslCTX) { ssl = SSL_new(sslCTX); if (ssl) { if (num) { SSL_set_connect_state(ssl); } else { SSL_set_accept_state(ssl); } SSL_set_verify(ssl, 0x3, SDMMD__ssl_verify_callback); SSL_set_verify_depth(ssl, 0x0); SSL_set_bio(ssl, bioSocket, bioSocket); SSL_set_ex_data(ssl, SDMMobileDevice->peer_certificate_data_index, (void*)deviceCert); result = SSL_do_handshake(ssl); if (result == 1) { SSL_CTX_free(sslCTX); } else { uint32_t err = SSL_get_error(ssl, result); if (err) { char *reason = SDMMD_ssl_strerror(ssl, err); printf("lockssl_handshake: SSL handshake fatal lower level error %d: %s.\n", err, reason); } else { char *reason = SDMMD_ssl_strerror(ssl, 0x0); printf("lockssl_handshake: SSL handshake controlled failure %d: %s.\n", err, reason); } SSL_free(ssl); } } else { printf("_create_ssl: Could not create SSL thing.\n"); } } } else { printf("_create_ssl_context: Could not decode private key.\n"); if (cert) { X509_free(cert); result = 0x0; } } } } else { printf("lockssl_handshake: Could not create SSL bio.\n"); } return ssl; }