Đây là giải pháp tôi đã tìm thấy bằng cách sử dụng thư viện OpenSSL. Tôi đang đăng câu hỏi và câu trả lời trên tràn ngăn xếp với hy vọng rằng nó sẽ tiết kiệm cho người khác những rắc rối và thời gian của việc tìm ra nó.
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/bio.h>
int main(int argc, char * argv[])
{
struct stat sb;
unsigned char * buff;
int fd;
ssize_t len;
BIO * bio;
X509 * x;
unsigned err;
int pos;
char errmsg[1024];
const EVP_MD * digest;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int n;
// checks arguments
if (argc != 2)
{
fprintf(stderr, "Usage: peminfo <pemfile>\n");
return(1);
};
// checks file
if ((stat(argv[1], &sb)) == -1)
{
perror("peminfo: stat()");
return(1);
};
len = (sb.st_size * 2);
// allocates memory
if (!(buff = malloc(len)))
{
fprintf(stderr, "peminfo: out of virtual memory\n");
return(1);
};
// opens file for reading
if ((fd = open(argv[1], O_RDONLY)) == -1)
{
perror("peminfo: open()");
free(buff);
return(1);
};
// reads file
if ((len = read(fd, buff, len)) == -1)
{
perror("peminfo: read()");
free(buff);
return(1);
};
// closes file
close(fd);
// initialize OpenSSL
SSL_load_error_strings();
SSL_library_init();
// creates BIO buffer
bio = BIO_new_mem_buf(buff, len);
// decodes buffer
if (!(x = PEM_read_bio_X509(bio, NULL, 0L, NULL)))
{
while((err = ERR_get_error()))
{
errmsg[1023] = '\0';
ERR_error_string_n(err, errmsg, 1023);
fprintf(stderr, "peminfo: %s\n", errmsg);
};
BIO_free(bio);
free(buff);
return(1);
};
// prints x509 info
printf("name: %s\n", x->name);
printf("serial: ");
printf("%02X", x->cert_info->serialNumber->data[0]);
for(pos = 1; pos < x->cert_info->serialNumber->length; pos++)
printf(":%02X", x->cert_info->serialNumber->data[pos]);
printf("\n");
// calculate & print fingerprint
digest = EVP_get_digestbyname("sha1");
X509_digest(x, digest, md, &n);
printf("Fingerprint: ");
for(pos = 0; pos < 19; pos++)
printf("%02x:", md[pos]);
printf("%02x\n", md[19]);
// frees memory
BIO_free(bio);
free(buff);
return(0);
}
Đây là biên dịch và đầu ra của chương trình trên:
$ cc -pedantic -W -Wall -Werror -O2 -Wno-deprecated -o peminfo peminfo.c \
> -lcrypto -lssl
$ ./peminfo /usr/local/etc/openldap/keys/ca-certs.pem
serial: 98:61:EB:C4:F2:C9:59:72
Fingerprint: 1d:59:d3:d4:4f:c9:e3:dc:f3:d7:66:b0:b8:7e:87:0b:01:73:c2:7e
Đây là kết quả từ các tiện ích openssl:
$ openssl x509 -noout -in /usr/local/etc/openldap/keys/ca-certs.pem \
> -fingerprint -serial
SHA1 Fingerprint=1D:59:D3:D4:4F:C9:E3:DC:F3:D7:66:B0:B8:7E:87:0B:01:73:C2:7E
serial=9861EBC4F2C95972
Nguồn
2012-03-17 11:18:47