Hi,
I'm working on a simple C-program to parse an X.509 certificate in PEM format, retrieve the public key and hash it so I can add this to a data package being sent to different remote sites and, at those sites, compare the hash to the subjectKeyIdentifier of the end-entity certificate and thus establish the first link in a chain of certificates. The program is up and running but I can't get the hash to match the subjectKeyIdentifier because the hash is running on the public key included in the certificate plus some extra bytes at the beginning of the key. The public key algorithm is id-ecPublicKey and from digging around on the internet a little bit I found that the extra bytes in front of the public key are identifying this fact. Here is an excerpt from the certificate I am using to test: Subject Public Key Info: Public Key Algorithm: id-ecPublicKey EC Public Key: pub: 04:00:71:b0:b1:69:5c:a2:db:26:fa:ef:96:d7:83: a3:1c:a6:44:4b:1b:5f:e7:a7:6f:dd:08:53:32:1e: b3:fc:73:87:a2:e3:90:fa:04:77:da:18:4f:58:49: fa:cd:78:1f:e6:3f:c4:70:a9:5a:7e:20:28:99:2a: 30:60:e9:e3:d4:07:f5:00:c8:1a:f0:f8:a4:33:74: ed:61:65:f3:d2:8c:39:37:af:95:02:d0:f2:70:08: b9:07:b8:de:21:31:03:d9:81:23:42:f3:84:80:5b: 9c:a9:eb:0d:f6:05:ce:cc:ee:69:54:f7:4e:4f:3d: e6:60:ac:b9:a1:cb:55:5f:39:22:f3:6d:23 ASN1 OID: secp521r1 And the output of the public key after I put it in DER format and print it in hex with the underlined part being the extra "header": Signer Public Key: 30:81:9b:30:10:06:07:2a:86:48:ce:3d:02:01:06:05:2b:81:04:00:23:03:81:86: 00:04:00:71:b0:b1:...matching public key...:55:5f:39:22:f3:6d:23 It is my first time using OpenSSL so there may be some piece of code I missed where I need to indicate the type of key it is so that I don't get these extra bytes. One way or the other, here is my code: int main(int argc, char *argv[]) { FILE * fp = NULL; X509 * x509 = NULL; EVP_PKEY * pubkey = NULL; const EVP_MD * md; EVP_MD_CTX ctx; unsigned char *certfile, *alg, *pubkey_der, *pubkey_der_next, *hash; unsigned int len; unsigned int * olen; int i; if (argc < 2) { printf("Usage: get_sid <cert_name.pem> [msg_digest]\n"); return -1; } certfile = strdup(argv[1]); if (argc > 2) { alg = strdup(argv[2]); } else { alg = strdup("sha1"); } printf("Reading end entity certificate\n"); //Open end entity certificate for x509 reading fp = fopen (certfile, "r"); free(certfile); if (fp == NULL) { return -1; } x509 = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); if (x509 == NULL) return -1; printf("Obtaining public key from x509 cert\n"); //Obtain public key from x509 pubkey = X509_get_pubkey(x509); X509_free(x509); if(pubkey == NULL) { return -1; } printf("Public key successfully obtained\n"); //Hash public key to obtain sid OpenSSL_add_all_digests(); if (!(md = EVP_get_digestbyname(alg))) { free(alg); return -1; } free(alg); if (!(hash = malloc(EVP_MAX_MD_SIZE))) { return -1; } //Convert pubkey into DER format for hash calculation pubkey_der = pubkey_der_next = (unsigned char *)malloc(200); len = i2d_PUBKEY(pubkey, &pubkey_der_next); printf("Signer Public Key: "); for (i = 0; i < len - 1; ++i) printf("%02x:", pubkey_der[i]); printf("%02x\n", pubkey_der[i]); EVP_DigestInit(&ctx, md); EVP_DigestUpdate(&ctx, pubkey_der, len); EVP_DigestFinal(&ctx, hash, olen); printf("SID: "); for (i = 0; i < *olen - 1; ++i) printf("%02x:", hash[i]); printf("%02x\n", hash[i]); free(hash); return 0; } Any suggestions to remove the extra bytes from the key (without doing a hardcode to do the DigestUpdate starting at element x) would be great. Any other suggestions would be appreciated as well since the library is huge and it being my first time, there may be some cleaner ways to execute this program. John Larson JIPM Systems Engineer, ViaSat Inc.