I wrote it in one hour for internal corporate usage.
cross-compiled:
mingw32-gcc -static -I /usr/local/mingw32/include/ -L/usr/local/mingw32/lib \ -o x509conv.exe x509conv.c \ -lssl -lcrypto -lgdi32
/* * x509conv.c * * Author, Copyright: Oleg Borodin <onborodin@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #include <stdio.h> #include <string.h> #include <openssl/x509.h> #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/x509.h> #include <unistd.h> void qexit(int code) { printf("# press enter key to continue\n"); getchar(); exit(code); } void readwrite_cert(char *ifilename, char *cn, size_t cn_size) { FILE* pemfile = fopen(ifilename, "r"); if (pemfile == NULL) { printf("# cannot open pem file %s, exit.\n", ifilename); qexit(1); } X509* x509 = PEM_read_X509(pemfile, NULL, NULL, NULL); printf("# open pem file %s\n", ifilename); if (x509 == NULL) { printf("# cannot find certificate in %s, exit.\n", ifilename); qexit(1); } char* subj = X509_NAME_oneline(X509_get_subject_name(x509), 0, 0); if (subj) { printf("# found subject: %s\n", subj); OPENSSL_free(subj); } X509_NAME *subject_name = X509_get_subject_name(x509); int nid_email = OBJ_txt2nid("CN"); X509_NAME_get_text_by_NID(subject_name, nid_email, cn, cn_size); printf("# cn is %s\n", cn); const int filename_maxsize = 256; char cert_filename[filename_maxsize]; memset(cert_filename, 0, sizeof(cert_filename)); strcat(cert_filename, cn); strcat(cert_filename, ".crt"); FILE* certfile = fopen(cert_filename, "w"); if (certfile == NULL) { printf("# cannot write certificate, exit.\n"); qexit(1); } PEM_write_X509(certfile, x509); printf("# wrote cert to %s\n", cert_filename); fclose(certfile); X509_free(x509); fclose(pemfile); } void readwrite_prikey(char *ifilename, char *cn) { FILE *pemfile = fopen(ifilename, "r"); if (pemfile == NULL) { printf("# cannot open pem file %s, exit.\n", ifilename); qexit(1); } RSA *prikey = PEM_read_RSAPrivateKey(pemfile, NULL, NULL, NULL); if (prikey == NULL) { printf("# cannot find key in file %s, exit.\n", ifilename); qexit(1); } printf("# read pem file %s\n", ifilename); const int filename_maxsize = 256; char prikey_filename[filename_maxsize]; memset(prikey_filename, 0, sizeof(prikey_filename)); strcat(prikey_filename, cn); strcat(prikey_filename, ".key"); FILE *keyfile = fopen(prikey_filename, "w"); if (keyfile != NULL) { PEM_write_RSAPrivateKey(keyfile, prikey, NULL, NULL, 0, 0, NULL); printf("# wrote key to %s\n", prikey_filename); } } int main(int argc, char** argv) { if(argc == 1) { printf("# no command line arguments, baby, I exit.\n"); qexit(1); } char *filename = argv[1]; if (strlen(filename) < 1) { printf("# zero file name, exit.\n"); qexit(1); } const size_t cn_size = 256; char cn[cn_size]; memset(cn, 0, cn_size); readwrite_cert(filename, cn, cn_size); readwrite_prikey(filename, cn); qexit(0); return 0; }
freebsd native.
$ cc -Wall -o x509conv x509conv.c -lssl -lcrypto $ ./x509conv a.pem # open pem file a.pem # found subject: /C=RU/O=Lazurit/CN=WRT Mosaic01 # cn is WRT Mosaic01 # wrote cert to WRT Mosaic01.crt # read pem file a.pem # wrote key to WRT Mosaic01.key $ ls -l *.crt *.key *.pem -rw-r--r-- 1 ziggi wheel 1497 19 Mar 17:09 a.crt -rw-r--r-- 1 ziggi wheel 1497 19 Mar 17:53 WRT Mosaic01.crt -rw-r--r-- 1 ziggi wheel 1675 19 Mar 17:53 WRT Mosaic01.key