📄 ca.c
字号:
#include <locale.h>#include "ca.h"#include <wchar.h>#include <openssl/pem.h>#include <openssl/x509.h>#include <openssl/x509v3.h>#include <openssl/pkcs12.h>#include <openssl/rand.h>#include <openssl/ssl.h>#include <openssl/engine.h>#define EXT_COPY_NONE 0#define EXT_COPY_ADD 1#define EXT_COPY_ALL 2#define debugint pass_cb(char *buf, int size, int rwflag, void *u) { int len; char *tmp; printf("Enter pass phrase for \"%s\"\n", u); tmp = "hello"; len = strlen(tmp); if (len <= 0) return 0; /* if too long, truncate */ if (len > size) len = size; memcpy(buf, tmp, len); return len; }X509 *load_cert(BIO *cert, int format,char * pwd ) //read certificate from DER、PEM、P12{ X509 * x=NULL; if (format == DER) x=d2i_X509_bio(cert,NULL); else if (format == PEM) x=PEM_read_bio_X509(cert,NULL,NULL,NULL);//PEM_read_bio_X509_AUX else if (format == P12) { PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL); PKCS12_parse(p12, pwd, NULL, &x, NULL); PKCS12_free(p12); p12 = NULL; } return(x);}X509 * LoadCert(char * cert,int certlen){ BIO * in=NULL; X509 * x509=NULL; if(certlen==0)//input is file { if((in=BIO_new_file(cert, "r")) == NULL) return NULL; } else//input is memory buf { if((in=BIO_new_mem_buf(cert,certlen))== NULL) return NULL; } if((x509=load_cert(in,DER,NULL))==NULL)// try DER { BIO_reset(in); x509=load_cert(in,PEM,NULL);//try PEM } if (in != NULL) BIO_free(in); return x509;}EVP_PKEY *load_key(BIO *bio, int format, char *pass){ EVP_PKEY *pkey=NULL; if (format == DER) { pkey=d2i_PrivateKey_bio(bio, NULL); } else if (format == PEM) { pkey=PEM_read_bio_PrivateKey(bio,NULL,NULL, pass); } else if (format == P12) { PKCS12 *p12 = d2i_PKCS12_bio(bio, NULL); PKCS12_parse(p12, pass, &pkey, NULL, NULL); PKCS12_free(p12); p12 = NULL; } return(pkey);}EVP_PKEY * LoadKey(char * key,int keylen,char * pass){ EVP_PKEY *pkey=NULL; BIO * in=NULL; /*char *passw="jianglei"; FILE *fp = fopen (key, "r"); if (fp == NULL) return NULL; pkey = PEM_read_PrivateKey(fp, NULL, NULL, passw);//pkey = PEM_read_PrivateKey(fp, NULL, NULL, pass); fclose (fp); if(pkey==NULL) {printf("pkey eoor\n");} return pkey;*/ if(keylen==0) { if((in=BIO_new_file(key, "r")) == NULL) return NULL; } else { if((in=BIO_new_mem_buf(key,keylen))== NULL) return NULL; } if((pkey=load_key(in,DER,pass))==NULL) { BIO_reset(in); pkey=load_key(in,PEM,pass); } if (in != NULL) BIO_free(in); return pkey;}int Rand(const char *file,int dont_warn){ int consider_randfile = (file == NULL); char buffer[200]; if (file == NULL) file = RAND_file_name(buffer, sizeof buffer); else if (RAND_egd(file) > 0) { return 1; } if (file == NULL || !RAND_load_file(file, -1)) { RAND_status() ; return 0; } return 1;}/* Add extension using V3 code: */int Add_ExtCert(X509 *cert,X509 * root, int nid, char *value){ X509_EXTENSION *ex; X509V3_CTX ctx; X509V3_set_ctx(&ctx,root, cert, NULL, NULL, 0); ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value); if (!ex) return 0; X509_add_ext(cert,ex,-1); X509_EXTENSION_free(ex); return 1;}long Add_Name(X509_NAME * x509name,int type/*c\cn*/,char * iput, int ilen){ wchar_t * ws,wc; ASN1_STRING stmp, *str = &stmp; UCHAR cbuf[256]={0}; int wslen, wcnt,i; char input[256]={0}; stmp.data=NULL; strncpy(input, iput, ilen); wslen = strlen(input)+1; if(wslen==1) return 1; ws =(wchar_t*)malloc(sizeof(wchar_t ) * wslen); if ((wcnt = mbstowcs(ws, input, wslen)) == -1) { free (ws); return 0; } for(i=0;i<(int)wcslen(ws);i++) { wc=ws[i]; cbuf[2*i]=wc/256; cbuf[2*i+1]=wc%256; } ASN1_mbstring_copy(&str, cbuf, 2*wslen, MBSTRING_BMP, B_ASN1_UTF8STRING); X509_NAME_add_entry_by_NID(x509name,type,V_ASN1_UTF8STRING,stmp.data,stmp.length, -1, 0); free (ws); return 1;}long mkRoot(stuSUBJECT * rootInfo,X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days){ X509 *x; EVP_PKEY *pk; RSA *rsa; X509_NAME *name=NULL; int i=0,len=0; if ((pkeyp == NULL) || (*pkeyp == NULL)) { if ((pk=EVP_PKEY_new()) == NULL) { abort(); return 0; } } else pk= *pkeyp; if ((x509p == NULL) || (*x509p == NULL)) { if ((x=X509_new()) == NULL) return 0; } else x= *x509p; Rand(NULL,1); rsa=RSA_generate_key(bits,RSA_F4,0,NULL); if (!EVP_PKEY_assign_RSA(pk,rsa)) { abort(); return 0; } rsa=NULL; X509_set_version(x,2);//version+1 ASN1_INTEGER_set(X509_get_serialNumber(x),serial);//serial no X509_gmtime_adj(X509_get_notBefore(x),0);//start date X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);//end date X509_set_pubkey(x,pk);//set pk name=X509_get_subject_name(x); setlocale(LC_CTYPE, "");#if(0) X509_NAME_add_entry_by_txt(name,"CC", MBSTRING_ASC, rootInfo->C, -1, -1, 0); X509_NAME_add_entry_by_txt(name,"ST", MBSTRING_ASC, rootInfo->ST, -1, -1, 0); X509_NAME_add_entry_by_txt(name,"L", MBSTRING_ASC, rootInfo->L, -1, -1, 0); X509_NAME_add_entry_by_txt(name,"O", MBSTRING_ASC, rootInfo->O, -1, -1, 0); X509_NAME_add_entry_by_txt(name,"OU", MBSTRING_ASC, rootInfo->OU, -1, -1, 0); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, rootInfo->CN, -1, -1, 0); X509_NAME_add_entry_by_txt(name,"M", MBSTRING_ASC, rootInfo->MAIL, -1, -1, 0);#else Add_Name(name,NID_countryName,(char *)rootInfo->C,sizeof(rootInfo->C)); Add_Name(name,NID_stateOrProvinceName,(char *)rootInfo->ST,sizeof(rootInfo->ST)); Add_Name(name,NID_localityName,(char *)rootInfo->L,sizeof(rootInfo->L) ); Add_Name(name,NID_organizationName,(char *)rootInfo->O,sizeof(rootInfo->O)); Add_Name(name,NID_organizationalUnitName,(char *)rootInfo->OU,sizeof(rootInfo->OU)); Add_Name(name,NID_commonName,(char *)rootInfo->CN,sizeof(rootInfo->CN)); Add_Name(name,NID_pkcs9_emailAddress,(char *)rootInfo->MAIL,sizeof(rootInfo->MAIL)); Add_Name(name,NID_email_protect,(char *)rootInfo->PMAIL,sizeof(rootInfo->PMAIL)); Add_Name(name,NID_title,(char *)rootInfo->T,sizeof(rootInfo->T)); Add_Name(name,NID_description,(char *)rootInfo->D,sizeof(rootInfo->D)); Add_Name(name,NID_givenName,(char *)rootInfo->G,sizeof(rootInfo->G)); Add_Name(name,NID_initials,(char *)rootInfo->I,sizeof(rootInfo->I)); Add_Name(name,NID_name,(char *)rootInfo->NAME,sizeof(rootInfo->NAME)); Add_Name(name,NID_surname,(char *)rootInfo->S,sizeof(rootInfo->S)); Add_Name(name,NID_dnQualifier,(char *)rootInfo->QUAL,sizeof(rootInfo->QUAL)); Add_Name(name,NID_pkcs9_unstructuredName,(char *)rootInfo->STN,sizeof(rootInfo->STN)); Add_Name(name,NID_pkcs9_challengePassword,(char *)rootInfo->PW,sizeof(rootInfo->PW)); Add_Name(name,NID_pkcs9_unstructuredAddress,(char *)rootInfo->ADD,sizeof(rootInfo->ADD)); #endif X509_set_issuer_name(x,name); /* Add various extensions: standard extensions */ Add_ExtCert(x,x,NID_basic_constraints, "critical,CA:TRUE"); Add_ExtCert(x,x,NID_subject_key_identifier, "hash"); Add_ExtCert(x,x,NID_authority_key_identifier, "keyid:always"); Add_ExtCert(x,x,NID_key_usage, "critical,keyCertSign,cRLSign,nonRepudiation,digitalSignature,keyEncipherment"); Add_ExtCert(x,x,NID_domainComponent, "no"); Add_ExtCert(x,x,NID_Domain, "no"); X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added if (!X509_sign(x,pk,EVP_sha1())) return 0; *x509p=x; *pkeyp=pk; return 1;}int add_ext(X509 *cert, int nid, char *value){ X509_EXTENSION *ex; X509V3_CTX ctx; /* This sets the 'context' of the extensions. */ /* No configuration database */ X509V3_set_ctx_nodb(&ctx); /* Issuer and subject certs: both the target since it is self signed, * no request and no CRL */ X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value); if (!ex) return 0; X509_add_ext(cert,ex,-1); X509_EXTENSION_free(ex); return 1;}static void callback(int p, int n, void *arg){ char c='B'; if (p == 0) c='.'; if (p == 1) c='+'; if (p == 2) c='*'; if (p == 3) c='\n'; fputc(c,stderr);}int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days){ X509 *x; EVP_PKEY *pk; RSA *rsa; X509_NAME *name=NULL; if ((pkeyp == NULL) || (*pkeyp == NULL)) { if ((pk=EVP_PKEY_new()) == NULL) { abort(); return(0); } } else pk= *pkeyp; if ((x509p == NULL) || (*x509p == NULL)) { if ((x=X509_new()) == NULL) return 0; } else x= *x509p; rsa=RSA_generate_key(bits,RSA_F4,callback,NULL); if (!EVP_PKEY_assign_RSA(pk,rsa)) { abort(); return 0; } rsa=NULL; X509_set_version(x,2); ASN1_INTEGER_set(X509_get_serialNumber(x),serial); X509_gmtime_adj(X509_get_notBefore(x),0); X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); X509_set_pubkey(x,pk); name=X509_get_subject_name(x); /* This function creates and adds the entry, working out the * correct string type and performing checks on its length. * Normally we'd check the return value for errors... */ X509_NAME_add_entry_by_txt(name,"C", MBSTRING_ASC, (unsigned char*)"UK", -1, -1, 0); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (unsigned char*)"OpenSSL Group", -1, -1, 0); /* Its self signed so set the issuer name to be the same as the * subject. */ X509_set_issuer_name(x,name); /* Add various extensions: standard extensions */ add_ext(x, NID_basic_constraints, "critical,CA:TRUE"); add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign"); add_ext(x, NID_subject_key_identifier, "hash"); /* Some Netscape specific extensions */ add_ext(x, NID_netscape_cert_type, "sslCA"); add_ext(x, NID_netscape_comment, "example comment extension"); #ifdef CUSTOM_EXT /* Maybe even add our own extension based on existing */ { int nid; nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension"); X509V3_EXT_add_alias(nid, NID_netscape_comment); add_ext(x, nid, "example comment alias"); }#endif if (!X509_sign(x,pk,EVP_md5())) return 0; *x509p=x; *pkeyp=pk; return(1);}int newroot(){ BIO *bio_err,*p,*c; X509 *x509=NULL; EVP_PKEY *pkey=NULL; // FILE *p=NULL; // FILE *c=NULL; p=BIO_new_file("new.key","w"); c=BIO_new_file("new.crt", "w"); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); bio_err=BIO_new_fp(stderr, BIO_NOCLOSE); mkcert(&x509,&pkey,1024,0,365); RSA_print_fp(stdout,pkey->pkey.rsa,0); X509_print_fp(stdout,x509); PEM_write_bio_PrivateKey(p,pkey,NULL,NULL,0,NULL, NULL); // PEM_write_PrivateKey(p,pkey,NULL,NULL,0,NULL, NULL); // PEM_write_X509(c,x509); PEM_write_bio_X509(c,x509); // BIO_free(fp); X509_free(x509); EVP_PKEY_free(pkey); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup();#endif CRYPTO_cleanup_all_ex_data(); CRYPTO_mem_leaks(bio_err); BIO_free(bio_err); BIO_free(p); BIO_free(c); return(0);}long MakeRoot(stuSUBJECT * rootInfo,int bits, int serial, int days,char * certFile,char * priFile, int type,char *pwd){ type=PEM; X509 *x509=NULL; EVP_PKEY *pkey=NULL; BIO * bcert=NULL,* bkey=NULL; long ret=1; int i=0,j=0; if(((bcert=BIO_new_file(certFile, "w"))== NULL)||((bkey=BIO_new_file(priFile, "w")) == NULL)) return 0; if(mkRoot(rootInfo,&x509,&pkey,bits,serial,days)) { if (type==DER) { i=i2d_X509_bio(bcert,x509);//returns 1 for success j=i2d_PrivateKey_bio(bkey,pkey); } else if(type==PEM) { i=PEM_write_bio_X509(bcert,x509); if(pwd) j= PEM_write_bio_PrivateKey(bkey, pkey, EVP_des_ede3_cbc(), NULL,0, 0, pwd); else j=PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL); } if(!i||!j) { ret=0; } } else ret=0; BIO_free(bcert); BIO_free(bkey); X509_free(x509); EVP_PKEY_free(pkey); return ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -