static int export_cert(CRYPT_CERTIFICATE cert, const char *filename) { int status; void *certData; int maxLength, actualLength; FILE *f; status = cryptExportCert( NULL, 0, &maxLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cert); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while getting max exported CA cert length\n", status); return status; } certData = malloc( maxLength ); if (certData == NULL) { /* not sure we can recover from this */ fprintf(stderr, "error allocating memory\n"); return CRYPT_ERROR_MEMORY; } actualLength = maxLength; status = cryptExportCert( certData, maxLength, &actualLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cert); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while getting max exported CA cert length\n", status); return status; } f = fopen(filename, "w"); if (f == NULL) { status = CRYPT_ERROR_PARAM2; goto err_certdata_exit; } fwrite(certData, actualLength, 1, f); fclose(f); return CRYPT_OK; err_certdata_exit: free(certData); return status; }
void createCSR(CRYPT_CONTEXT keyContext) { CRYPT_CERTIFICATE cryptCertRequest; void *certRequest; int certRequestMaxLength, certRequestLength; FILE *f = NULL; int status; /* Create a certification request and add the public key to it */ status = cryptCreateCert( &cryptCertRequest, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTREQUEST ); if (status != CRYPT_OK) { fprintf(stderr, "Error creating certRequest\n"); exit(1); } status = cryptSetAttribute( cryptCertRequest, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, keyContext ); if (status != CRYPT_OK) { fprintf(stderr, "Error setting pubkey: %d\n", status); exit(1); } /* Add identification information */ status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_COUNTRYNAME, "US", 2); if (status != CRYPT_OK) { fprintf(stderr, "Error setting C\n"); exit(1); } status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_ORGANIZATIONNAME, "example", 7); if (status != CRYPT_OK) { fprintf(stderr, "Error setting O\n"); exit(1); } status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_COMMONNAME, "example", 7); if (status != CRYPT_OK) { fprintf(stderr, "Error setting CN\n"); exit(1); } /* Sign the certification request with the private key and export it */ status = cryptSignCert( cryptCertRequest, keyContext ); if (status != CRYPT_OK) { fprintf(stderr, "Error signing CSR\n"); exit(1); } status = cryptExportCert( NULL, 0, &certRequestMaxLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cryptCertRequest ); if (status != CRYPT_OK) { fprintf(stderr, "Error getting max cert length\n"); exit(1); } certRequest = malloc( certRequestMaxLength ); status = cryptExportCert( certRequest, certRequestMaxLength, &certRequestLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cryptCertRequest); if (status != CRYPT_OK) { fprintf(stderr, "Error exporting cert\n"); exit(1); } /* Destroy the certification request */ status = cryptDestroyCert( cryptCertRequest ); if (status != CRYPT_OK) { fprintf(stderr, "Error destroying cert request\n"); exit(1); } f = fopen(CSR_FILE, "w"); if (!f) { perror("fopen CSR_FILE"); exit(1); } fwrite(certRequest, certRequestLength, 1, f); fclose(f); free(certRequest); }
void show_export_crl_dialog(FRONTEND * fe) { /* export dialog -> * dialog (OK, cancel), * filename entry & browse, * format choice (DER, text) */ GtkWidget *dlg; GtkEntry *filename_entry; GtkButton *browse_button; GtkRadioButton *rb_text, *rb_der; GtkBox *box; gint result; dlg = gtk_dialog_new_with_buttons("Export CRL", GTK_WINDOW(fe->mainWindow), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); box = GTK_BOX(gtk_hbox_new(0, 5)); gtk_box_pack_start(box, gtk_label_new("Export to"), FALSE, FALSE, 0); filename_entry = GTK_ENTRY(gtk_entry_new()); gtk_box_pack_start(box, GTK_WIDGET(filename_entry), FALSE, FALSE, 0); browse_button = GTK_BUTTON(gtk_button_new_with_mnemonic("_Browse...")); gtk_box_pack_start(box, GTK_WIDGET(browse_button), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(browse_button), "clicked", G_CALLBACK(on_browse_button_clicked), dlg); /* don't ref the entry -- same lifetime */ g_object_set_data_full(G_OBJECT(browse_button), "entry", filename_entry, NULL); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), GTK_WIDGET(box), FALSE, FALSE, 0); rb_der = GTK_RADIO_BUTTON(gtk_radio_button_new_with_mnemonic (NULL, "_DER (Binary)")); rb_text = GTK_RADIO_BUTTON(gtk_radio_button_new_with_mnemonic_from_widget (rb_der, "_PEM (Text)")); box = GTK_BOX(gtk_hbox_new(0, 5)); gtk_box_pack_start(box, gtk_label_new("Format:"), FALSE, FALSE, 0); gtk_box_pack_start(box, GTK_WIDGET(rb_der), FALSE, FALSE, 0); gtk_box_pack_start(box, GTK_WIDGET(rb_text), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), GTK_WIDGET(box), FALSE, FALSE, 0); gtk_widget_show_all(GTK_WIDGET(GTK_DIALOG(dlg)->vbox)); result = gtk_dialog_run(GTK_DIALOG(dlg)); if (result == GTK_RESPONSE_ACCEPT) { void *buf; int status; int len; gboolean text_format; CRYPT_CERTFORMAT_TYPE fmt; FILE *f; gchar *filename; CRYPT_CERTIFICATE crl; CRYPT_CONTEXT key; gchar *password; /* get password */ password = do_get_password(GTK_WINDOW(dlg)); if (password == NULL) { /* cancelled? */ goto cleanup; } /* sign */ status = lmz_ca_get_signing_key(fe->db, password, &key); g_free(password); /* dynamic */ if (status == CRYPT_ERROR_WRONGKEY) { show_error_dialog(GTK_WINDOW(dlg), "Wrong password"); goto cleanup; } else if (!cryptStatusOK(status)) { show_error_dialog(GTK_WINDOW(dlg), "Error getting signing key (cryptlib error %d)", status); goto cleanup; } status = lmz_ca_gen_crl(fe->db, &crl); if (cryptStatusOK(status)) { /* sign it */ status = cryptSignCert(crl, key); if (cryptStatusOK(status)) { text_format = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rb_text)); fmt = text_format ? CRYPT_CERTFORMAT_TEXT_CERTIFICATE : CRYPT_CERTFORMAT_CERTIFICATE; status = cryptExportCert(NULL, 0, &len, fmt, crl); buf = malloc(len); status = cryptExportCert(buf, len, &len, fmt, crl); if (cryptStatusOK(status)) { filename = g_filename_from_utf8(gtk_entry_get_text(filename_entry), -1, NULL, NULL, NULL); if (filename != NULL) { f = fopen(filename, "w"); if (f != NULL) { if (fwrite(buf, len, 1, f) != 1) { show_error_dialog(NULL, "error fully writing data"); } fclose(f); } else { show_error_dialog(NULL, "error opening file for writing"); } g_free(filename); } else { show_error_dialog(NULL, "filename conversion error"); } free(buf); } } else { show_error_dialog(NULL, "error signing crl (cl error %d)", status); } cryptDestroyCert(crl); } else { show_error_dialog(NULL, "error generating crl (cl error %d)", status); } cryptDestroyContext(key); } cleanup: gtk_widget_destroy(dlg); }
static int generateKey( const int keyBits, const char *certRequestFileName ) { CRYPT_KEYSET cryptKeyset; CRYPT_CERTIFICATE cryptCertRequest; CRYPT_CONTEXT cryptKey; FILE *filePtr; BYTE certBuffer[ BUFFER_SIZE ]; char filenameBuffer[ FILENAME_BUFFER_SIZE ]; void *fileNamePtr = filenameBuffer; int length, count, status; /* Generate a key to certify. We can't just reuse the built-in test key because this has already been used as the CA key and the keyset code won't allow it to be added to a keyset as both a CA key and user key, so we have to generate a new one */ status = cryptCreateContext( &cryptKey, CRYPT_UNUSED, CRYPT_ALGO_ECDSA ); if( cryptStatusOK( status ) ) status = cryptSetAttribute( cryptKey, CRYPT_CTXINFO_KEYSIZE, keyBits >> 3 ); if( cryptStatusOK( status ) ) { status = cryptSetAttributeString( cryptKey, CRYPT_CTXINFO_LABEL, USER_PRIVKEY_LABEL, paramStrlen( USER_PRIVKEY_LABEL ) ); } if( cryptStatusOK( status ) ) status = cryptGenerateKey( cryptKey ); if( cryptStatusError( status ) ) { printf( "Key generation failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } /* Create the certificate request for the new key */ status = cryptCreateCert( &cryptCertRequest, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTREQUEST ); if( cryptStatusOK( status ) ) status = cryptSetAttribute( cryptCertRequest, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptKey ); if( cryptStatusOK( status ) && \ !addCertFields( cryptCertRequest, certRequestData, __LINE__ ) ) return( FALSE ); if( cryptStatusOK( status ) ) status = cryptSignCert( cryptCertRequest, cryptKey ); if( cryptStatusOK( status ) ) { status = cryptExportCert( certBuffer, BUFFER_SIZE, &length, CRYPT_CERTFORMAT_CERTIFICATE, cryptCertRequest ); cryptDestroyCert( cryptCertRequest ); } if( cryptStatusError( status ) ) { printf( "Certificate request creation failed with error code %d, " "line %d.\n", status, __LINE__ ); return( FALSE ); } if( ( filePtr = fopen( certRequestFileName, "wb" ) ) != NULL ) { count = fwrite( certBuffer, 1, length, filePtr ); fclose( filePtr ); } if( filePtr == NULL || count < length ) { printf( "Couldn't write certificate request to disk, line %d.\n", __LINE__ ); return( FALSE ); } /* Create the keyset and add the private key to it */ filenameFromTemplate( filenameBuffer, SERVER_ECPRIVKEY_FILE_TEMPLATE, keyBits ); status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, fileNamePtr, CRYPT_KEYOPT_CREATE ); if( cryptStatusError( status ) ) { printf( "cryptKeysetOpen() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } status = cryptAddPrivateKey( cryptKeyset, cryptKey, TEST_PRIVKEY_PASSWORD ); if( cryptStatusError( status ) ) { printExtError( cryptKeyset, "cryptAddPrivateKey()", status, __LINE__ ); return( FALSE ); } cryptDestroyContext( cryptKey ); cryptKeysetClose( cryptKeyset ); return( TRUE ); }