/************************************************************************** * * G e n e r a t e S e l f S i g n e d O b j e c t S i g n i n g C e r t * *phew*^ * */ static CERTCertificate* GenerateSelfSignedObjectSigningCert(char *nickname, CERTCertDBHandle *db, char *subject, unsigned long serial, int keysize, char *token) { CERTCertificate * cert, *temp_cert; SECItem * derCert; CERTCertificateRequest * req; PK11SlotInfo * slot = NULL; SECKEYPrivateKey * privk = NULL; SECKEYPublicKey * pubk = NULL; if ( token ) { slot = PK11_FindSlotByName(token); } else { slot = PK11_GetInternalKeySlot(); } if (slot == NULL) { PR_fprintf(errorFD, "Can't find PKCS11 slot %s\n", token ? token : ""); errorCount++; exit (ERRX); } if ( GenerateKeyPair(slot, &pubk, &privk, keysize) != SECSuccess) { FatalError("Error generating keypair."); } req = make_cert_request (subject, pubk); temp_cert = make_cert (req, serial, &req->subject); if (set_cert_type(temp_cert, NS_CERT_TYPE_OBJECT_SIGNING | NS_CERT_TYPE_OBJECT_SIGNING_CA) != SECSuccess) { FatalError("Unable to set cert type"); } derCert = sign_cert (temp_cert, privk); cert = install_cert(db, derCert, nickname); if (ChangeTrustAttributes(db, cert, ",,uC") != SECSuccess) { FatalError("Unable to change trust on generated certificate"); } /* !!! Free memory ? !!! */ PK11_FreeSlot(slot); SECKEY_DestroyPrivateKey(privk); SECKEY_DestroyPublicKey(pubk); return cert; }
/* * Create an EE or CA certificate using the * table to set the fields. The table is build * using command line arguments */ int create_cert( struct object_field *table) { int ret = 0; int i; struct Certificate cert; Certificate(&cert, (ushort) 0); // constructor for the cert struct char *keyfile = NULL, *val; int val_type; eecert = 0; // is it a ca or ee cert if ((ret = setEEorCA(table)) != SUCCESS) return ret; setSelfSigned(table); // Read the certificate template into the certificate if (!templateFile) { if (eecert) templateFile = CONFIG_TEMPLATE_EE_CERT_get(); else templateFile = CONFIG_TEMPLATE_CA_CERT_get(); } ret = get_casn_file(&cert.self, (char *)templateFile, 0); if (ret < 0) { warn(FILE_OPEN_ERR, (char *)templateFile); return (FILE_OPEN_ERR); } // clear out fields in the template (only keeping a few); clear_cert(&cert); // fill in the default fields write_default_fields(&cert); // Populate the certificate fields with data from the // table. Note the table is populated from input arguments // If there is no function to call and the argument is optional then // it is ok otherwise it is an error. for (i = 0; table[i].name != NULL; i++) { if (table[i].func != NULL) { if (table[i].value != NULL) { if (table[i].func(&cert.self, table[i].value) < 0) { fprintf(stderr, "Error writing %s into field %s\n", table[i].value, table[i].name); } } else { if (table[i].required) fprintf(stderr, "Missing value for %s\n", table[i].name); } } } // if signature value is set in the table, write that value as the // signature, // otherwise sign it if (get_table_value("signatureValue", table, &val, &val_type) != 0) { fprintf(stdout, "Error writing signature"); return (-1); } if (val != NULL) // input signature { if (write_sig(&cert, val) != SUCCESS) { fprintf(stdout, "Error writing signature"); return (-1); } } else { // have to sign it, get key from subject // keyfile if selfsigned else parents if (selfSigned) get_table_value("subjkeyfile", table, &keyfile, &val_type); else get_table_value("parentkeyfile", table, &keyfile, &val_type); if (keyfile == NULL || (sign_cert(&cert, keyfile) != SUCCESS)) return -1; } // write out the certificate using the ouput filename if (get_table_value("outputfilename", table, &val, &val_type) < 0) { warn(FILE_WRITE_ERR, "outputfilename missing"); return (FILE_WRITE_ERR); } if (put_casn_file(&cert.self, val, 0) < 0) { warn(FILE_WRITE_ERR, val); return (FILE_WRITE_ERR); } else warn(SUCCESS, val); return (SUCCESS); }