Estoy intentando hacer un programa que utiliza algunos servicios web en Delphi XE. Para conectarme a los servicios web, tengo que usar un certificado autofirmado, que se almacena en la tienda de certificados de Windows. Abrí la tienda de certificados con CertOpenSystemStore, obtuve el certificado con CertFindCertificateInStore
y lo configuré con SSL_CTX_use_certificate
. No hay problema con esto Luego llego el blob de clave pública con CryptExportKey
y compone una clave privada así:Uso de certificado y clave privada de Windows cert store con OpenSSL
function PrivKeyBlob2RSA(const AKeyBlob: PByte; const ALength: Integer; const ASSLCtx: PSSL_CTX): IdSSLOpenSSLHeaders.PEVP_PKEY;
var
modulus: PByte;
bh: PBLOBHEADER;
rp: PRSAPUBKEY;
rsa_modlen: DWORD;
rsa_modulus: PAnsiChar;
rkey: PRSA;
begin
bh := PBLOBHEADER(AKeyBlob);
Assert(bh^.bType = PUBLICKEYBLOB);
rp := PRSAPUBKEY(AKeyBlob + 8);
Assert(rp.magic = $31415352);
rsa_modulus := PAnsiChar(Integer(Pointer(rp))+12);
rkey := RSA_new_method(ASSLCtx.client_cert_engine);
rkey^.References := 1;
rkey^.e := BN_new;
rkey^.n := BN_new;
BN_set_word(rkey^.e, rp^.pubexp);
rsa_modlen := (rp^.bitlen div 8) + 1;
modulus := AllocMem(rsa_modlen);
CopyMemory(modulus, rsa_modulus, rsa_modlen);
RevBuffer(modulus, rsa_modlen);
BN_bin2bn(modulus, rsa_modlen, rkey^.n);
Result := EVP_PKEY_new;
EVP_PKEY_assign_RSA(Result, PAnsiChar(rkey));
end;
luego lo configuro con SSL_CTX_use_PrivateKey
y SSL_CTX_check_private_key
- ningún problema hasta el momento. Pero cuando comienza la transferencia de datos, aparece una infracción de acceso en libeay32.dll. Si cargo la clave desde el archivo .pem, todo está bien. No puedo ver lo que estoy haciendo mal, por favor ayuda :)
Aquí es el mensaje de error exacto: violación
acceso a 09881C5F dirección en el módulo 'libeay32.dll'. Leído de dirección 00000000.
La versión de libeay32.dll es 1.0.0.5. Intenté con la versión 0.9.algo también: recibí el mismo error, solo una dirección diferente.
A continuación se muestra la estructura de RSA consigo en PrivKeyBlob2RSA
:
pad 0
version 0
meth $898030C
engine nil
n $A62D508
e $A62D4D8
d nil
p nil
q nil
dmp1 nil
dmq1 nil
iqmp nil
ex_data (nil, -1163005939 {$BAADF00D})
references 1
flags 6
_method_mod_n nil
_method_mod_p nil
_method_mod_q nil
bignum_data nil {#0}
blinding nil
mt_blinding nil
Revisé los n y e bignums, y que son correctos, y todo lo demás se ve bien. Y sí, el error ocurre al llamar a la función ssl_read
.
Bienvenido a StackOverflow. Me temo que "obtengo una infracción de acceso en libea32.dll" no nos da información para intentar ayudarte. Si recibe un mensaje de error o una excepción o AV, es ** muy ** importante incluir el mensaje de error ** exacto ** (junto con las direcciones de memoria). Si no nos proporciona ese medio, lo pedimos y luego esperamos a que nos lo entregue antes de que podamos intentar ayudarlo. Si proporcionas la información de error en tu pregunta original (junto con el código y el texto de la pregunta como has proporcionado), obtendrás una respuesta mucho más rápido. Por favor edítalo y agrégalo. Gracias. :) –
Las excepciones con la 'Lectura de la dirección 0x00000000' en Delphi casi siempre (no el 100% del tiempo, pero casi) son causadas por acceder a un objeto antes de su creación, o un puntero que nunca tiene asignado ningún elemento (un puntero). ¿Puedes limitar el lugar en el código que está causando la violación de acceso? (+1 para una buena pregunta después de la edición, BTW.) –
@Ken White Gracias por la respuesta. De alguna manera, no puedo alinear el código muy bien en el comentario, así que edité la pregunta. La estructura de RSA me parece bien ... – Andrejs