Search code examples
delphiopenssl

Is there a chance to deal with unknown format of private key & certificate?


I'm working on a Delphi project where I will sign an invoice. I tested some OpenSSL Delphi ports and I had success in signing and verifying data. The problem is that I can't read either the key or the certificate files. I think there is a problem with key and certificate formats.

Private key (private-key.pem)

MHQCAQEEIP0tXvA0mhzTBgjZaAGt+V3tWIr79nG/gs56jKFJb6gboAcGBSuBBAAKoUQDQgAE+39UxFUCaF5p51RTvwXL+YODEpITlTdI27S72pSPJEAjQs2jBb1sLS/xg8/y5555+d19KoLmLo6gMrxvINXaHw==

Certificate (cert.pem)

MIID6zCCA5CgAwIBAgITbwAAgLTUs0JsZqZVAQABAACAtDAKBggqhkjOPQQDAjBjMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxEzARBgoJkiaJk/IsZAEZFgNnb3YxFzAVBgoJkiaJk/IsZAEZFgdleHRnYXp0MRwwGgYDVQQDExNUU1pFSU5WT0lDRS1TdWJDQS0xMB4XDTIyMTAwNjEyNTcyNloXDTI0MTAwNTEyNTcyNlowTjELMAkGA1UEBhMCU0ExEzARBgNVBAoTCjM5OTk5OTk5OTkxDDAKBgNVBAsTA1RTVDEcMBoGA1UEAxMTVFNULTM5OTk5OTk5OTkwMDAwMzBWMBAGByqGSM49AgEGBSuBBAAKA0IABGGDDKDmhWAITDv7LXqLX2cmr6+qddUkpcLCvWs5rC2O29W/hS4ajAK4Qdnahym6MaijX75Cg3j4aao7ouYXJ9GjggI5MIICNTCBmgYDVR0RBIGSMIGPpIGMMIGJMTswOQYDVQQEDDIxLVRTVHwyLVRTVHwzLTA3MzBlZThlLTA4OWQtNDQ1OS1hMzg3LWIxMTg5NGJmMTQyOTEfMB0GCgmSJomT8ixkAQEMDzM5OTk5OTk5OTkwMDAwMzENMAsGA1UEDAwEMTEwMDEMMAoGA1UEGgwDVFNUMQwwCgYDVQQPDANUU1QwHQYDVR0OBBYEFDuWYlOzWpFN3no1WtyNktQdrA8JMB8GA1UdIwQYMBaAFHZgjPsGoKxnVzWdz5qspyuZNbUvME4GA1UdHwRHMEUwQ6BBoD+GPWh0dHA6Ly90c3RjcmwuemF0Y2EuZ292LnNhL0NlcnRFbnJvbGwvVFNaRUlOVk9JQ0UtU3ViQ0EtMS5jcmwwga0GCCsGAQUFBwEBBIGgMIGdMG4GCCsGAQUFBzABhmJodHRwOi8vdHN0Y3JsLnphdGNhLmdvdi5zYS9DZXJ0RW5yb2xsL1RTWkVpbnZvaWNlU0NBMS5leHRnYXp0Lmdvdi5sb2NhbF9UU1pFSU5WT0lDRS1TdWJDQS0xKDEpLmNydDArBggrBgEFBQcwAYYfaHR0cDovL3RzdGNybC56YXRjYS5nb3Yuc2Evb2NzcDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMDMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwIwCgYIKwYBBQUHAwMwCgYIKoZIzj0EAwIDSQAwRgIhAOZ8oJnliPhdWvCiokPmStz2niL+1Rbw6y9asAh229z7AiEA0r6l1qnq6vzRjVvr9Hnbtq/9Aki0R4rF64EFNY4XACM=

Code to read private key

    bp := BIO_new_file(PAnsiChar(PrivKeyFile), 'r');
    if CheckError() then Exit;
    try
      FPrivateKeyData := PEM_read_bio_PrivateKey(bp, nil, nil, PAnsiChar(FCertPassword));
      if CheckError() then Exit;
    finally
      BIO_free(bp);
    end;

Code to read certificate

  bp := BIO_new_file(PAnsiChar(certFile), 'r');
  if CheckError then Exit;
  try
   _x509 := PEM_read_bio_X509(bp, nil, nil, PAnsiChar(FCertPassword));
   if CheckError then Exit;
  finally
    BIO_free(bp);
  end;

Error Message in both cases

error:0906D06C:PEM routines:PEM_read_bio:no start line

If files format is not accepted by OpenSSL, is there any way to convert files format so I can use them with OpenSSL library?


Solution

  • PEM IS NOT JUST BASE64. Your files names say .pem and you try to read them with routines that handle PEM, but they aren't PEM. PEM is base64 (of certain data types) with linebreaks and with header/trailer lines -- these are not optional; see rfc7468. Your previous Q had these correct and only the 'type' in the header/trailer wrong.

    Add header/trailer lines and linebreaks as follows (edit: corrected privatekey type) and your files will work with your code:

    -----BEGIN EC PRIVATE KEY-----
    MHQCAQEEIP0tXvA0mhzTBgjZaAGt+V3tWIr79nG/gs56jKFJb6gboAcGBSuBBAAK
    oUQDQgAE+39UxFUCaF5p51RTvwXL+YODEpITlTdI27S72pSPJEAjQs2jBb1sLS/x
    g8/y5555+d19KoLmLo6gMrxvINXaHw==
    -----END EC PRIVATE KEY-----
    
    -----BEGIN CERTIFICATE-----
    MIID6zCCA5CgAwIBAgITbwAAgLTUs0JsZqZVAQABAACAtDAKBggqhkjOPQQDAjBj
    MRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxEzARBgoJkiaJk/IsZAEZFgNnb3YxFzAV
    BgoJkiaJk/IsZAEZFgdleHRnYXp0MRwwGgYDVQQDExNUU1pFSU5WT0lDRS1TdWJD
    QS0xMB4XDTIyMTAwNjEyNTcyNloXDTI0MTAwNTEyNTcyNlowTjELMAkGA1UEBhMC
    U0ExEzARBgNVBAoTCjM5OTk5OTk5OTkxDDAKBgNVBAsTA1RTVDEcMBoGA1UEAxMT
    VFNULTM5OTk5OTk5OTkwMDAwMzBWMBAGByqGSM49AgEGBSuBBAAKA0IABGGDDKDm
    hWAITDv7LXqLX2cmr6+qddUkpcLCvWs5rC2O29W/hS4ajAK4Qdnahym6MaijX75C
    g3j4aao7ouYXJ9GjggI5MIICNTCBmgYDVR0RBIGSMIGPpIGMMIGJMTswOQYDVQQE
    DDIxLVRTVHwyLVRTVHwzLTA3MzBlZThlLTA4OWQtNDQ1OS1hMzg3LWIxMTg5NGJm
    MTQyOTEfMB0GCgmSJomT8ixkAQEMDzM5OTk5OTk5OTkwMDAwMzENMAsGA1UEDAwE
    MTEwMDEMMAoGA1UEGgwDVFNUMQwwCgYDVQQPDANUU1QwHQYDVR0OBBYEFDuWYlOz
    WpFN3no1WtyNktQdrA8JMB8GA1UdIwQYMBaAFHZgjPsGoKxnVzWdz5qspyuZNbUv
    ME4GA1UdHwRHMEUwQ6BBoD+GPWh0dHA6Ly90c3RjcmwuemF0Y2EuZ292LnNhL0Nl
    cnRFbnJvbGwvVFNaRUlOVk9JQ0UtU3ViQ0EtMS5jcmwwga0GCCsGAQUFBwEBBIGg
    MIGdMG4GCCsGAQUFBzABhmJodHRwOi8vdHN0Y3JsLnphdGNhLmdvdi5zYS9DZXJ0
    RW5yb2xsL1RTWkVpbnZvaWNlU0NBMS5leHRnYXp0Lmdvdi5sb2NhbF9UU1pFSU5W
    T0lDRS1TdWJDQS0xKDEpLmNydDArBggrBgEFBQcwAYYfaHR0cDovL3RzdGNybC56
    YXRjYS5nb3Yuc2Evb2NzcDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYB
    BQUHAwIGCCsGAQUFBwMDMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwIwCgYI
    KwYBBQUHAwMwCgYIKoZIzj0EAwIDSQAwRgIhAOZ8oJnliPhdWvCiokPmStz2niL+
    1Rbw6y9asAh229z7AiEA0r6l1qnq6vzRjVvr9Hnbtq/9Aki0R4rF64EFNY4XACM=
    -----END CERTIFICATE-----
    

    Alternatively, you can decode the base64 to binary and then use the routines that parse binary rather than PEM, for this case d2i_ECPrivateKey and d2i_x509.

    Note this privatekey is not encrypted, so you don't actually need the password (it is ignored).

    Meta: I'm not sure this is really programming or development, but I needed formatting so I answered. If Q is closed, I will delete if requested.