int signRequest(char* pemRequest, int days, char* pemCAKey, char* pemCaCert, int certType, char *url, char* result) { BIO* bioReq = BIO_new_mem_buf(pemRequest, -1); BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1); BIO* bioCert = BIO_new_mem_buf(pemCaCert, -1); X509* caCert = PEM_read_bio_X509(bioCert, NULL, NULL, NULL); int err = 0; X509_REQ *req=NULL; if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) { BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return ERR_peek_error(); } EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL); if (!caKey) { BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return ERR_peek_error(); } X509* cert = X509_new(); EVP_PKEY* reqPub; if(!(err = X509_set_version(cert, 2))) { BIO_free(bioReq); BIO_free(bioCAKey); return ERR_peek_error(); } //redo all the certificate details, because OpenSSL wants us to work hard X509_set_issuer_name(cert, X509_get_subject_name(caCert)); ASN1_UTCTIME *s=ASN1_UTCTIME_new(); // Jira-issue: WP-37 // This is temp solution for putting pzp validity 5 minutes before current time // If there is a small clock difference between machines, it results in cert_not_yet_valid // It does set GMT time but is relevant to machine time. // A better solution would be to have ntp server contacted to get a proper time. if(certType == 2) { X509_gmtime_adj(s, long(0-300)); } else { X509_gmtime_adj(s, long(0)); } // End of WP-37 X509_set_notBefore(cert, s); X509_gmtime_adj(s, (long)60*60*24*days); X509_set_notAfter(cert, s); ASN1_UTCTIME_free(s); X509_set_subject_name(cert, X509_REQ_get_subject_name(req)); reqPub = X509_REQ_get_pubkey(req); X509_set_pubkey(cert,reqPub); EVP_PKEY_free(reqPub); //create a serial number at random ASN1_INTEGER* serial = getRandomSN(); X509_set_serialNumber(cert, serial); X509_EXTENSION *ex; X509V3_CTX ctx; X509V3_set_ctx_nodb(&ctx); X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); char *str = (char*)malloc(strlen("caIssuers;") + strlen(url) + 1); if (str == NULL) { return -10; } strcpy(str, "caIssuers;"); strcat(str, url); if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_info_access, (char*)str))) { free(str); return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } free(str); if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_issuer_alt_name, (char*)"issuer:copy"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if( certType == 1) { if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } } else if( certType == 2) { if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } } if (!(err = X509_sign(cert,caKey,EVP_sha1()))) { BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return err; } BIO *mem = BIO_new(BIO_s_mem()); PEM_write_bio_X509(mem,cert); BUF_MEM *bptr; BIO_get_mem_ptr(mem, &bptr); BIO_read(mem, result, bptr->length); BIO_free(mem); BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return 0; }
int selfSignRequest(char* pemRequest, int days, char* pemCAKey, int certType, char *url, char* result) { BIO* bioReq = BIO_new_mem_buf(pemRequest, -1); BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1); int err = 0; X509_REQ *req=NULL; if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) { BIO_free(bioReq); BIO_free(bioCAKey); return -5; } EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL); if (!caKey) { BIO_free(bioReq); BIO_free(bioCAKey); return -6; } X509* cert = X509_new(); EVP_PKEY* reqPub; //redo all the certificate details, because OpenSSL wants us to work hard if(!(err = X509_set_version(cert, 2))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } if(!(err = X509_set_issuer_name(cert, X509_REQ_get_subject_name(req)))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } ASN1_UTCTIME *s=ASN1_UTCTIME_new(); // Jira-issue: WP-37 // This is temp solution for putting pzp validity 5 minutes before current time // If there is a small clock difference between machines, it results in cert_not_yet_valid // It does set GMT time but is relevant to machine time. // A better solution would be to have ntp server contacted to get proper time. if(certType == 2) { X509_gmtime_adj(s, long(0-300)); } else { X509_gmtime_adj(s, long(0)); } // End of WP-37 X509_set_notBefore(cert, s); X509_gmtime_adj(s, (long)60*60*24*days); X509_set_notAfter(cert, s); ASN1_UTCTIME_free(s); if(!(err = X509_set_subject_name(cert, X509_REQ_get_subject_name(req)))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } if (!(reqPub = X509_REQ_get_pubkey(req))) { BIO_free(bioReq); BIO_free(bioCAKey); return -7; } err = X509_set_pubkey(cert,reqPub); EVP_PKEY_free(reqPub); if (!err) { return err; // an error occurred, this is terrible style. } //create a serial number at random ASN1_INTEGER* serial = getRandomSN(); X509_set_serialNumber(cert, serial); // V3 extensions X509_EXTENSION *ex; X509V3_CTX ctx; X509V3_set_ctx_nodb(&ctx); X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if( certType == 0) { if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:TRUE"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_key_usage, (char*)"critical, keyCertSign, digitalSignature, cRLSign"))) { /* critical, keyCertSign,cRLSign, nonRepudiation,*/ return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, serverAuth"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_inhibit_any_policy, (char*)"0"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_crl_distribution_points, (char*)url))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } } if (!(err = X509_sign(cert,caKey,EVP_sha1()))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } BIO *mem = BIO_new(BIO_s_mem()); PEM_write_bio_X509(mem,cert); BUF_MEM *bptr; BIO_get_mem_ptr(mem, &bptr); BIO_read(mem, result, bptr->length); BIO_free(mem); BIO_free(bioReq); BIO_free(bioCAKey); return 0; }
int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data) { long *aLong = NULL; PKI_TIME *aTime = NULL; PKI_INTEGER *aInt = NULL; PKI_X509_NAME *aName = NULL; PKI_X509_KEYPAIR_VALUE *aKey = NULL; int ret = 0; LIBPKI_X509_CERT *xVal = NULL; LIBPKI_X509_ALGOR *alg = NULL; // PKI_X509_CERT_VALUE *xVal = NULL; if ( !x || !x->value || !data || x->type != PKI_DATATYPE_X509_CERT) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (PKI_ERR); } // xVal = PKI_X509_get_value( x ); xVal = x->value; switch( type ) { case PKI_X509_DATA_VERSION: aLong = (long *) data; ret = X509_set_version( xVal, *aLong ); break; case PKI_X509_DATA_SERIAL: aInt = (PKI_INTEGER *) data; ret = X509_set_serialNumber( xVal, aInt); break; case PKI_X509_DATA_SUBJECT: aName = (PKI_X509_NAME *) data; ret = X509_set_subject_name( xVal, aName ); break; case PKI_X509_DATA_ISSUER: aName = (PKI_X509_NAME *) data; ret = X509_set_issuer_name( xVal, aName ); break; case PKI_X509_DATA_NOTBEFORE: aTime = (PKI_TIME *) data; ret = X509_set_notBefore( xVal, aTime ); break; case PKI_X509_DATA_NOTAFTER: aTime = (PKI_TIME *) data; ret = X509_set_notAfter( xVal, aTime ); break; case PKI_X509_DATA_KEYPAIR_VALUE: aKey = data; ret = X509_set_pubkey( xVal, aKey); break; case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG1: alg = data; #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (xVal->cert_info != NULL) xVal->cert_info->signature = alg; #else // Transfer Ownership xVal->cert_info.signature.algorithm = alg->algorithm; xVal->cert_info.signature.parameter = alg->parameter; // Remove the transfered data alg->algorithm = NULL; alg->parameter = NULL; // Free memory X509_ALGOR_free((X509_ALGOR *)data); data = NULL; #endif // Ok ret = 1; break; case PKI_X509_DATA_SIGNATURE_ALG2: // if (xVal->sig_alg != NULL ) X509_ALGOR_free(xVal->sig_alg); alg = data; #if OPENSSL_VERSION_NUMBER < 0x1010000fL xVal->sig_alg = alg; #else // Transfer Ownership xVal->sig_alg.algorithm = alg->algorithm; xVal->sig_alg.parameter = alg->parameter; // Remove the transfered data alg->algorithm = NULL; alg->parameter = NULL; // Free memory X509_ALGOR_free((X509_ALGOR *)alg); data = NULL; // Ok ret = 1; #endif break; default: /* Not Recognized/Supported DATATYPE */ ret = 0; break; } if (!ret) return PKI_ERR; return PKI_OK; }
CFMutableDictionaryRef SDMMD__CreatePairingMaterial(CFDataRef devicePubkey) { CFMutableDictionaryRef record = NULL; RSA *rsaBIOData = NULL; BIO *deviceBIO = SDMMD__create_bio_from_data(devicePubkey); if (deviceBIO) { PEM_read_bio_RSAPublicKey(deviceBIO, &rsaBIOData, NULL, NULL); BIO_free(deviceBIO); } else { printf("Could not decode device public key\\n"); } RSA *rootKeyPair = RSA_generate_key(2048, 65537, NULL, NULL); if (!rootKeyPair) { printf("Could not allocate root key pair\n"); } RSA *hostKeyPair = RSA_generate_key(2048, 65537, NULL, NULL); if (!hostKeyPair) { printf("Could not allocate host key pair\n"); } sdmmd_return_t result = kAMDSuccess; EVP_PKEY *rootEVP = EVP_PKEY_new(); if (!rootEVP) { printf("Could not allocate root EVP key\\n"); } else { result = EVP_PKEY_assign(rootEVP, EVP_CTRL_RAND_KEY, PtrCast(rootKeyPair, char *)); if (!result) { printf("Could not assign root key pair\n"); } } EVP_PKEY *hostEVP = EVP_PKEY_new(); if (!hostEVP) { printf("Could not allocate host EVP key\\n"); } else { result = EVP_PKEY_assign(hostEVP, EVP_CTRL_RAND_KEY, PtrCast(hostKeyPair, char *)); if (!result) { printf("Could not assign host key pair\n"); } } EVP_PKEY *deviceEVP = EVP_PKEY_new(); if (!deviceEVP) { printf("Could not allocate device EVP key\\n"); } else { result = EVP_PKEY_assign(deviceEVP, EVP_CTRL_RAND_KEY, PtrCast(rsaBIOData, char *)); if (!result) { printf("Could not assign device key pair\n"); } } X509 *rootX509 = X509_new(); if (!rootX509) { printf("Could not create root X509\\n"); } else { X509_set_pubkey(rootX509, rootEVP); X509_set_version(rootX509, 2); ASN1_INTEGER *rootSerial = X509_get_serialNumber(rootX509); ASN1_INTEGER_set(rootSerial, 0); ASN1_TIME *rootAsn1time = ASN1_TIME_new(); ASN1_TIME_set(rootAsn1time, 0); X509_set_notBefore(rootX509, rootAsn1time); ASN1_TIME_set(rootAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years X509_set_notAfter(rootX509, rootAsn1time); ASN1_TIME_free(rootAsn1time); SDMMD__add_ext(rootX509, NID_basic_constraints, "critical,CA:TRUE"); SDMMD__add_ext(rootX509, NID_subject_key_identifier, "hash"); result = X509_sign(rootX509, rootEVP, EVP_sha1()); if (!result) { printf("Could not sign root cert\\n"); } } X509 *hostX509 = X509_new(); if (!hostX509) { printf("Could not create host X509\\n"); } else { X509_set_pubkey(hostX509, hostEVP); X509_set_version(hostX509, 2); ASN1_INTEGER *hostSerial = X509_get_serialNumber(hostX509); ASN1_INTEGER_set(hostSerial, 0); ASN1_TIME *hostAsn1time = ASN1_TIME_new(); ASN1_TIME_set(hostAsn1time, 0); X509_set_notBefore(hostX509, hostAsn1time); ASN1_TIME_set(hostAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years X509_set_notAfter(hostX509, hostAsn1time); ASN1_TIME_free(hostAsn1time); SDMMD__add_ext(hostX509, NID_basic_constraints, "critical,CA:FALSE"); SDMMD__add_ext(hostX509, NID_subject_key_identifier, "hash"); SDMMD__add_ext(hostX509, NID_key_usage, "critical,digitalSignature,keyEncipherment"); result = X509_sign(hostX509, rootEVP, EVP_sha1()); if (!result) { printf("Could not sign host cert\\n"); } } X509 *deviceX509 = X509_new(); if (!deviceX509) { printf("Could not create device X509\\n"); } else { X509_set_pubkey(deviceX509, deviceEVP); X509_set_version(deviceX509, 2); ASN1_INTEGER *deviceSerial = X509_get_serialNumber(deviceX509); ASN1_INTEGER_set(deviceSerial, 0); ASN1_TIME *deviceAsn1time = ASN1_TIME_new(); ASN1_TIME_set(deviceAsn1time, 0); X509_set_notBefore(deviceX509, deviceAsn1time); ASN1_TIME_set(deviceAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years X509_set_notAfter(deviceX509, deviceAsn1time); ASN1_TIME_free(deviceAsn1time); SDMMD__add_ext(deviceX509, NID_basic_constraints, "critical,CA:FALSE"); SDMMD__add_ext(deviceX509, NID_subject_key_identifier, "hash"); SDMMD__add_ext(deviceX509, NID_key_usage, "critical,digitalSignature,keyEncipherment"); result = X509_sign(deviceX509, rootEVP, EVP_sha1()); if (!result) { printf("Could not sign device cert\\n"); } } CFDataRef rootCert = SDMMD_CreateDataFromX509Certificate(rootX509); CFDataRef hostCert = SDMMD_CreateDataFromX509Certificate(hostX509); CFDataRef deviceCert = SDMMD_CreateDataFromX509Certificate(deviceX509); CFDataRef rootPrivKey = SDMMD_CreateDataFromPrivateKey(rootEVP); CFDataRef hostPrivKey = SDMMD_CreateDataFromPrivateKey(hostEVP); CFStringRef hostId = SDMMD_CreateUUID(); record = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (record) { CFDictionarySetValue(record, CFSTR("RootCertificate"), rootCert); CFDictionarySetValue(record, CFSTR("HostCertificate"), hostCert); CFDictionarySetValue(record, CFSTR("DeviceCertificate"), deviceCert); CFDictionarySetValue(record, CFSTR("RootPrivateKey"), rootPrivKey); CFDictionarySetValue(record, CFSTR("HostPrivateKey"), hostPrivKey); CFDictionarySetValue(record, CFSTR("HostID"), hostId); } CFSafeRelease(rootCert); CFSafeRelease(hostCert); CFSafeRelease(deviceCert); CFSafeRelease(rootPrivKey); CFSafeRelease(hostPrivKey); CFSafeRelease(hostId); Safe(EVP_PKEY_free, rootEVP); Safe(EVP_PKEY_free, hostEVP); Safe(EVP_PKEY_free, deviceEVP); Safe(X509_free, rootX509); Safe(X509_free, hostX509); Safe(X509_free, deviceX509); return record; }
KSSLCertificate* KSSLCertificateFactory::generateSelfSigned(KSSLKeyType /*keytype*/) { #if 0 //#ifdef KSSL_HAVE_SSL X509_NAME *x509name = X509_NAME_new(); X509 *x509; ASN1_UTCTIME *beforeafter; KSSLCertificate *newcert; int rc; // FIXME: generate the private key if (keytype == KEYTYPE_UNKNOWN || (key=EVP_PKEY_new()) == NULL) { X509_NAME_free(x509name); return NULL; } switch(keytype) { case KEYTYPE_RSA: if (!EVP_PKEY_assign_RSA(key, RSA_generate_key(newkey,0x10001, req_cb,bio_err))) { } break; case KEYTYPE_DSA: if (!DSA_generate_key(dsa_params)) goto end; if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end; dsa_params=NULL; if (pkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); break; } // FIXME: dn doesn't exist // FIXME: allow the notAfter value to be parameterized // FIXME: allow a password to lock the key with // Fill in the certificate X509_NAME_add_entry_by_NID(x509name, OBJ_txt2nid("CN"), 0x1001, (unsigned char *) dn, -1, -1, 0); x509 = X509_new(); rc = X509_set_issuer_name(x509, x509name); if (rc != 0) { X509_free(x509); X509_NAME_free(x509name); return NULL; } rc = X509_set_subject_name(x509, x509name); if (rc != 0) { X509_free(x509); X509_NAME_free(x509name); return NULL; } ASN1_INTEGER_set(X509_get_serialNumber(*x509), 0); X509_NAME_free(x509name); // Make it a 1 year certificate beforeafter = ASN1_UTCTIME_new(); if (!X509_gmtime_adj(beforeafter, -60*60*24)) { // yesterday X509_free(x509); return NULL; } if (!X509_set_notBefore(x509, beforeafter)) { X509_free(x509); return NULL; } if (!X509_gmtime_adj(beforeafter, 60*60*24*364)) { // a year from yesterday X509_free(x509); return NULL; } if (!X509_set_notAfter(x509, beforeafter)) { X509_free(x509); return NULL; } ASN1_UTCTIME_free(beforeafter); if (!X509_set_pubkey(x509, key)) { X509_free(x509); return NULL; } rc = X509_sign(x509, key, EVP_sha1()); if (rc != 0) { X509_free(x509); return NULL; } newCert = new KSSLCertificate; newCert->setCert(x509); return newCert; #else return NULL; #endif }
int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data) { long *aLong = NULL; PKI_TIME *aTime = NULL; PKI_INTEGER *aInt = NULL; PKI_X509_NAME *aName = NULL; PKI_X509_KEYPAIR_VALUE *aKey = NULL; int ret = 0; PKI_X509_CERT_VALUE *xVal = NULL; if( !x || !x->value || !data) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (PKI_ERR); } xVal = PKI_X509_get_value( x ); switch( type ) { case PKI_X509_DATA_VERSION: aLong = (long *) data; ret = X509_set_version( xVal, *aLong ); break; case PKI_X509_DATA_SERIAL: aInt = (PKI_INTEGER *) data; ret = X509_set_serialNumber( xVal, aInt); break; case PKI_X509_DATA_SUBJECT: aName = (PKI_X509_NAME *) data; ret = X509_set_subject_name( xVal, aName ); break; case PKI_X509_DATA_ISSUER: aName = (PKI_X509_NAME *) data; ret = X509_set_issuer_name( xVal, aName ); break; case PKI_X509_DATA_NOTBEFORE: aTime = (PKI_TIME *) data; ret = X509_set_notBefore( xVal, aTime ); break; case PKI_X509_DATA_NOTAFTER: aTime = (PKI_TIME *) data; ret = X509_set_notAfter( xVal, aTime ); break; case PKI_X509_DATA_KEYPAIR_VALUE: aKey = data; ret = X509_set_pubkey( xVal, aKey); break; case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG1: if (xVal->cert_info != NULL) { // if (xVal->cert_info->signature != NULL) X509_ALGOR_free(xVal->cert_info->signature); xVal->cert_info->signature = (X509_ALGOR *) data; } break; case PKI_X509_DATA_SIGNATURE_ALG2: // if (xVal->sig_alg != NULL ) X509_ALGOR_free(xVal->sig_alg); xVal->sig_alg = (X509_ALGOR *) data; break; default: /* Not Recognized/Supported DATATYPE */ ret = 0; break; } if (!ret) return PKI_ERR; return PKI_OK; }
// Import a newly generated RSA1024 pvt key and a certificate // to every slot and use the key to sign some data static void test_import_and_sign_all_10_RSA() { EVP_PKEY *evp; RSA *rsak; X509 *cert; ASN1_TIME *tm; CK_BYTE i, j; CK_BYTE some_data[32]; CK_BYTE e[] = {0x01, 0x00, 0x01}; CK_BYTE p[64]; CK_BYTE q[64]; CK_BYTE dp[64]; CK_BYTE dq[64]; CK_BYTE qinv[64]; BIGNUM *e_bn; CK_ULONG class_k = CKO_PRIVATE_KEY; CK_ULONG class_c = CKO_CERTIFICATE; CK_ULONG kt = CKK_RSA; CK_BYTE id = 0; CK_BYTE sig[64]; CK_ULONG recv_len; CK_BYTE value_c[3100]; CK_ULONG cert_len; CK_BYTE der_encoded[80]; CK_BYTE_PTR der_ptr; CK_BYTE_PTR r_ptr; CK_BYTE_PTR s_ptr; CK_ULONG r_len; CK_ULONG s_len; unsigned char *px; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_CLASS, &class_k, sizeof(class_k)}, {CKA_KEY_TYPE, &kt, sizeof(kt)}, {CKA_ID, &id, sizeof(id)}, {CKA_PUBLIC_EXPONENT, e, sizeof(e)}, {CKA_PRIME_1, p, sizeof(p)}, {CKA_PRIME_2, q, sizeof(q)}, {CKA_EXPONENT_1, dp, sizeof(dp)}, {CKA_EXPONENT_2, dq, sizeof(dq)}, {CKA_COEFFICIENT, qinv, sizeof(qinv)} }; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_CLASS, &class_c, sizeof(class_c)}, {CKA_ID, &id, sizeof(id)}, {CKA_VALUE, value_c, sizeof(value_c)} }; CK_OBJECT_HANDLE obj[24]; CK_SESSION_HANDLE session; CK_MECHANISM mech = {CKM_RSA_PKCS, NULL}; evp = EVP_PKEY_new(); if (evp == NULL) exit(EXIT_FAILURE); rsak = RSA_new(); if (rsak == NULL) exit(EXIT_FAILURE); e_bn = BN_bin2bn(e, 3, NULL); if (e_bn == NULL) exit(EXIT_FAILURE); asrt(RSA_generate_key_ex(rsak, 1024, e_bn, NULL), 1, "GENERATE RSAK"); asrt(BN_bn2bin(rsak->p, p), 64, "GET P"); asrt(BN_bn2bin(rsak->q, q), 64, "GET Q"); asrt(BN_bn2bin(rsak->dmp1, dp), 64, "GET DP"); asrt(BN_bn2bin(rsak->dmq1, dp), 64, "GET DQ"); asrt(BN_bn2bin(rsak->iqmp, qinv), 64, "GET QINV"); if (EVP_PKEY_set1_RSA(evp, rsak) == 0) exit(EXIT_FAILURE); cert = X509_new(); if (cert == NULL) exit(EXIT_FAILURE); if (X509_set_pubkey(cert, evp) == 0) exit(EXIT_FAILURE); tm = ASN1_TIME_new(); if (tm == NULL) exit(EXIT_FAILURE); ASN1_TIME_set_string(tm, "000001010000Z"); X509_set_notBefore(cert, tm); X509_set_notAfter(cert, tm); cert->sig_alg->algorithm = OBJ_nid2obj(8); cert->cert_info->signature->algorithm = OBJ_nid2obj(8); ASN1_BIT_STRING_set_bit(cert->signature, 8, 1); ASN1_BIT_STRING_set(cert->signature, "\x00", 1); px = value_c; if ((cert_len = (CK_ULONG) i2d_X509(cert, &px)) == 0 || cert_len > sizeof(value_c)) exit(EXIT_FAILURE); publicKeyTemplate[2].ulValueLen = cert_len; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1"); asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); for (i = 0; i < 24; i++) { id = i; asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT"); asrt(funcs->C_CreateObject(session, privateKeyTemplate, 9, obj + i), CKR_OK, "IMPORT KEY"); } asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); for (i = 0; i < 24; i++) { for (j = 0; j < 10; j++) { if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1) exit(EXIT_FAILURE); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit"); recv_len = sizeof(sig); asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign"); /* r_len = 32; */ /* s_len = 32; */ /* der_ptr = der_encoded; */ /* *der_ptr++ = 0x30; */ /* *der_ptr++ = 0xff; // placeholder, fix below */ /* r_ptr = sig; */ /* *der_ptr++ = 0x02; */ /* *der_ptr++ = r_len; */ /* if (*r_ptr >= 0x80) { */ /* *(der_ptr - 1) = *(der_ptr - 1) + 1; */ /* *der_ptr++ = 0x00; */ /* } */ /* else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { */ /* r_len--; */ /* *(der_ptr - 1) = *(der_ptr - 1) - 1; */ /* r_ptr++; */ /* } */ /* memcpy(der_ptr, r_ptr, r_len); */ /* der_ptr+= r_len; */ /* s_ptr = sig + 32; */ /* *der_ptr++ = 0x02; */ /* *der_ptr++ = s_len; */ /* if (*s_ptr >= 0x80) { */ /* *(der_ptr - 1) = *(der_ptr - 1) + 1; */ /* *der_ptr++ = 0x00; */ /* } */ /* else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { */ /* s_len--; */ /* *(der_ptr - 1) = *(der_ptr - 1) - 1; */ /* s_ptr++; */ /* } */ /* memcpy(der_ptr, s_ptr, s_len); */ /* der_ptr+= s_len; */ /* der_encoded[1] = der_ptr - der_encoded - 2; */ /* dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); */ /* asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); */ } } asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }
// Import a newly generated P256 pvt key and a certificate // to every slot and use the key to sign some data static void test_import_and_sign_all_10() { EVP_PKEY *evp; EC_KEY *eck; const EC_POINT *ecp; const BIGNUM *bn; char pvt[32]; X509 *cert; ASN1_TIME *tm; CK_BYTE i, j; CK_BYTE some_data[32]; CK_ULONG class_k = CKO_PRIVATE_KEY; CK_ULONG class_c = CKO_CERTIFICATE; CK_ULONG kt = CKK_ECDSA; CK_BYTE id = 0; CK_BYTE params[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; CK_BYTE sig[64]; CK_ULONG recv_len; CK_BYTE value_c[3100]; CK_ULONG cert_len; CK_BYTE der_encoded[80]; CK_BYTE_PTR der_ptr; CK_BYTE_PTR r_ptr; CK_BYTE_PTR s_ptr; CK_ULONG r_len; CK_ULONG s_len; unsigned char *p; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_CLASS, &class_k, sizeof(class_k)}, {CKA_KEY_TYPE, &kt, sizeof(kt)}, {CKA_ID, &id, sizeof(id)}, {CKA_EC_PARAMS, ¶ms, sizeof(params)}, {CKA_VALUE, pvt, sizeof(pvt)} }; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_CLASS, &class_c, sizeof(class_c)}, {CKA_ID, &id, sizeof(id)}, {CKA_VALUE, value_c, sizeof(value_c)} }; CK_OBJECT_HANDLE obj[24]; CK_SESSION_HANDLE session; CK_MECHANISM mech = {CKM_ECDSA, NULL}; evp = EVP_PKEY_new(); if (evp == NULL) exit(EXIT_FAILURE); eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (eck == NULL) exit(EXIT_FAILURE); asrt(EC_KEY_generate_key(eck), 1, "GENERATE ECK"); bn = EC_KEY_get0_private_key(eck); asrt(BN_bn2bin(bn, pvt), 32, "EXTRACT PVT"); if (EVP_PKEY_set1_EC_KEY(evp, eck) == 0) exit(EXIT_FAILURE); cert = X509_new(); if (cert == NULL) exit(EXIT_FAILURE); if (X509_set_pubkey(cert, evp) == 0) exit(EXIT_FAILURE); tm = ASN1_TIME_new(); if (tm == NULL) exit(EXIT_FAILURE); ASN1_TIME_set_string(tm, "000001010000Z"); X509_set_notBefore(cert, tm); X509_set_notAfter(cert, tm); cert->sig_alg->algorithm = OBJ_nid2obj(8); cert->cert_info->signature->algorithm = OBJ_nid2obj(8); ASN1_BIT_STRING_set_bit(cert->signature, 8, 1); ASN1_BIT_STRING_set(cert->signature, "\x00", 1); p = value_c; if ((cert_len = (CK_ULONG) i2d_X509(cert, &p)) == 0 || cert_len > sizeof(value_c)) exit(EXIT_FAILURE); publicKeyTemplate[2].ulValueLen = cert_len; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1"); asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); for (i = 0; i < 24; i++) { id = i; asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT"); asrt(funcs->C_CreateObject(session, privateKeyTemplate, 5, obj + i), CKR_OK, "IMPORT KEY"); } asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); for (i = 0; i < 24; i++) { for (j = 0; j < 10; j++) { if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1) exit(EXIT_FAILURE); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit"); recv_len = sizeof(sig); asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign"); r_len = 32; s_len = 32; der_ptr = der_encoded; *der_ptr++ = 0x30; *der_ptr++ = 0xff; // placeholder, fix below r_ptr = sig; *der_ptr++ = 0x02; *der_ptr++ = r_len; if (*r_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { r_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; r_ptr++; } memcpy(der_ptr, r_ptr, r_len); der_ptr+= r_len; s_ptr = sig + 32; *der_ptr++ = 0x02; *der_ptr++ = s_len; if (*s_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { s_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; s_ptr++; } memcpy(der_ptr, s_ptr, s_len); der_ptr+= s_len; der_encoded[1] = der_ptr - der_encoded - 2; dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); } } asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }