Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to verify the password of a pkcs#12 certificate (.PXF) with openssl C API?

Tags:

c

openssl

pkcs#12

I have an .pxf (AFAIK PKCS#12) certificate. How can I confirm a given password for this certificate using the openssl C API?

like image 819
Tilo Prütz Avatar asked Jan 13 '11 09:01

Tilo Prütz


2 Answers

One approach to finding answers like this is to find an OpenSSL utility that performs the same functionality as what you are trying to do. In this case, you can use the pkcs12 utility that comes with OpenSSL to verify the password.

The command to verify a pfx file is the following:

openssl pkcs12 -in mypfx.pfx -noout

With that information, you can then look at its source code ({openssl_src}/apps/pkcs12.c) to see how they do it.

The source code shows that it calls PKCS12_verify_mac to verify the password. First to verify that there is no password:

if( PKCS12_verify_mac(p12, NULL, 0) )
{
    printf("PKCS12 has no password.\n");
}

And then if there is a password, verify it by passing it as an argument:

if( PKCS12_verify_mac(p12, password, -1) )
{
    printf("PKCS12 password matches.\n");
}

OpenSSL also has demos for working with PKCS12 in openssl/demos/pkcs12. The pkread.c demo provides an example for parsing a pfx file with a password.

EVP_PKEY *pkey;
X509 *cert;
STACK_OF(X509) *ca = NULL;

if (!PKCS12_parse(p12, password, &pkey, &cert, &ca)) {
    fprintf(stderr, "Error parsing PKCS#12 file\n");
    ERR_print_errors_fp(stderr);
    exit(1);
}

Full example, compiled with gcc -std=c99 verifypfx.c -o verifypfx -lcrypto:

#include <stdio.h>
#include <errno.h>
#include <openssl/pkcs12.h>
#include <openssl/err.h>

int main(int argc, char *argv[])
{
        const char *password = "mypassword";
        PKCS12 *p12;

        // Load the pfx file.
        FILE *fp = fopen("mypfx.pfx", "rb");
        if( fp == NULL ) { perror("fopen"); return 1; }
        p12 = d2i_PKCS12_fp(fp, NULL);
        fclose(fp);

        OpenSSL_add_all_algorithms();
        ERR_load_PKCS12_strings();

        if( p12 == NULL ) { ERR_print_errors_fp(stderr); exit(1); }

        // Note:  No password is not the same as zero-length password.  Check for both.
        if( PKCS12_verify_mac(p12, NULL, 0) )
        {
                printf("PKCS12 has no password.\n");
        }
        else if( PKCS12_verify_mac(p12, password, -1) )
        {
                printf("PKCS12 password matches.\n");
        }
        else
        {
                printf("Password not correct.\n");
        }

        return 0;
}
like image 70
indiv Avatar answered Sep 19 '22 15:09

indiv


Use PKCS12_verify_mac(). eg.

FILE* f = fopen("myfile.pfx", "rb");
PKCS12* p12 = d2i_PKCS12_fp(f, NULL);
fclose(f);
if (!PKCS12_verify_mac(p12, (char*)"mypassword", strlen("mypassword")))
{
   // handle failure
}
like image 24
FractalSpace Avatar answered Sep 17 '22 15:09

FractalSpace