static int detect_signtrust( sc_pkcs15_card_t *p15card ){ if(insert_cert(p15card,"8000DF01C000", 0x45, 1, "Signatur Zertifikat")) return 1; p15card->tokeninfo->manufacturer_id = strdup("Deutsche Post"); p15card->tokeninfo->label = strdup("SignTrust Card"); insert_cert(p15card,"800082008220", 0x46, 1, "Verschluesselungs Zertifikat"); insert_cert(p15card,"800083008320", 0x47, 1, "Authentifizierungs Zertifikat"); insert_key(p15card,"8000DF015331", 0x45, 0x80, 1024, 1, "Signatur Schluessel"); insert_key(p15card,"800082008210", 0x46, 0x80, 1024, 2, "Verschluesselungs Schluessel"); insert_key(p15card,"800083008310", 0x47, 0x80, 1024, 3, "Authentifizierungs Schluessel"); insert_pin(p15card,"8000DF010000", 1, 0, 0x81, 6, "Signatur PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); insert_pin(p15card,"800082000040", 2, 0, 0x81, 6, "Verschluesselungs PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); insert_pin(p15card,"800083000040", 3, 0, 0x81, 6, "Authentifizierungs PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); return 0; }
bool Certificate_Store_In_SQL::insert_key(const X509_Certificate& cert, const Private_Key& key) { insert_cert(cert); if(find_key(cert)) return false; auto pkcs8 = PKCS8::BER_encode(key, m_rng, m_password); auto fpr = key.fingerprint("SHA-256"); auto stmt1 = m_database->new_statement( "INSERT OR REPLACE INTO " + m_prefix + "keys ( fingerprint, key ) VALUES ( ?1, ?2 )"); stmt1->bind(1,fpr); stmt1->bind(2,pkcs8.data(),pkcs8.size()); stmt1->spin(); auto stmt2 = m_database->new_statement( "UPDATE " + m_prefix + "certificates SET priv_fingerprint = ?1 WHERE fingerprint == ?2"); stmt2->bind(1,fpr); stmt2->bind(2,cert.fingerprint("SHA-256")); stmt2->spin(); return true; }
static int detect_datev( sc_pkcs15_card_t *p15card ){ if(insert_cert(p15card,"3000C500", 0x45, 0, "Signatur Zertifikat")) return 1; p15card->tokeninfo->manufacturer_id = strdup("DATEV"); p15card->tokeninfo->label = strdup("DATEV Classic"); insert_cert(p15card,"DF02C200", 0x46, 0, "Verschluesselungs Zertifikat"); insert_cert(p15card,"DF02C500", 0x47, 0, "Authentifizierungs Zertifikat"); insert_key(p15card,"30005371", 0x45, 0x82, 1024, 1, "Signatur Schluessel"); insert_key(p15card,"DF0253B1", 0x46, 0x81, 1024, 1, "Verschluesselungs Schluessel"); insert_key(p15card,"DF025371", 0x47, 0x82, 1024, 1, "Authentifizierungs Schluessel"); insert_pin(p15card,"5001", 1, 0, 0x01, 6, "PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED ); return 0; }
static int detect_unicard( sc_pkcs15_card_t *p15card ){ if(!insert_cert(p15card,"41004352", 0x45, 1, "Zertifikat 1")){ p15card->tokeninfo->manufacturer_id = strdup("JLU Giessen"); p15card->tokeninfo->label = strdup("JLU Giessen Card"); insert_cert(p15card,"41004353", 0x46, 1, "Zertifikat 2"); insert_cert(p15card,"41004354", 0x47, 1, "Zertifikat 3"); insert_key(p15card,"41005103", 0x45, 0x83, 1024, 1, "Schluessel 1"); insert_key(p15card,"41005104", 0x46, 0x84, 1024, 1, "Schluessel 2"); insert_key(p15card,"41005105", 0x47, 0x85, 1024, 1, "Schluessel 3"); } else if(!insert_cert(p15card,"41014352", 0x45, 1, "Zertifikat 1")){ p15card->tokeninfo->manufacturer_id = strdup("TU Darmstadt"); p15card->tokeninfo->label = strdup("TUD Card"); insert_cert(p15card,"41014353", 0x46, 1, "Zertifikat 2"); insert_cert(p15card,"41014354", 0x47, 1, "Zertifikat 3"); insert_key(p15card,"41015103", 0x45, 0x83, 1024, 1, "Schluessel 1"); insert_key(p15card,"41015104", 0x46, 0x84, 1024, 1, "Schluessel 2"); insert_key(p15card,"41015105", 0x47, 0x85, 1024, 1, "Schluessel 3"); } else return 1; insert_pin(p15card,"5000", 1, 2, 0x00, 6, "PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED ); insert_pin(p15card,"5008", 2, 0, 0x01, 8, "PUK", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN ); return 0; }
static int detect_idkey( sc_pkcs15_card_t *p15card ){ sc_card_t *card=p15card->card; sc_path_t p; /* TCKEY-Applikation ? */ memset(&p, 0, sizeof(sc_path_t)); p.type=SC_PATH_TYPE_DF_NAME; memcpy(p.value, "\xD2\x76\x00\x00\x03\x0C\x01", p.len=7); if (sc_select_file(card,&p,NULL)!=SC_SUCCESS) return 1; p15card->tokeninfo->manufacturer_id = strdup("TeleSec GmbH"); p15card->tokeninfo->label = strdup("IDKey Card"); insert_cert(p15card, "DF074331", 0x45, 1, "Signatur Zertifikat 1"); insert_cert(p15card, "DF074332", 0x45, 1, "Signatur Zertifikat 2"); insert_cert(p15card, "DF074333", 0x45, 1, "Signatur Zertifikat 3"); insert_key(p15card, "DF074E03", 0x45, 0x84, 2048, 1, "IDKey1"); insert_key(p15card, "DF074E04", 0x46, 0x85, 2048, 1, "IDKey2"); insert_key(p15card, "DF074E05", 0x47, 0x86, 2048, 1, "IDKey3"); insert_key(p15card, "DF074E06", 0x48, 0x87, 2048, 1, "IDKey4"); insert_key(p15card, "DF074E07", 0x49, 0x88, 2048, 1, "IDKey5"); insert_key(p15card, "DF074E08", 0x4A, 0x89, 2048, 1, "IDKey6"); insert_pin(p15card, "5000", 1, 2, 0x00, 6, "PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED ); insert_pin(p15card, "5001", 2, 0, 0x01, 8, "PUK", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN ); return 0; }
// Revocation void Certificate_Store_In_SQL::revoke_cert(const X509_Certificate& cert, CRL_Code code, const X509_Time& time) { insert_cert(cert); auto stmt1 = m_database->new_statement( "INSERT OR REPLACE INTO " + m_prefix + "revoked ( fingerprint, reason, time ) VALUES ( ?1, ?2, ?3 )"); stmt1->bind(1,cert.fingerprint("SHA-256")); stmt1->bind(2,code); if(time.time_is_set()) { DER_Encoder der; time.encode_into(der); stmt1->bind(3,der.get_contents_unlocked()); } else { stmt1->bind(3,-1); } stmt1->spin(); }
static int detect_netkey( sc_pkcs15_card_t *p15card ){ sc_card_t *card=p15card->card; sc_path_t p; sc_file_t *f; int keylen; char dir[10]; const char *c_auth; /* NKS-Applikation ? */ memset(&p, 0, sizeof(sc_path_t)); p.type=SC_PATH_TYPE_DF_NAME; memcpy(p.value, "\xD2\x76\x00\x00\x03\x01\x02", p.len=7); if (sc_select_file(card,&p,&f)!=SC_SUCCESS) return 1; sprintf(dir,"%04X", f->id); sc_file_free(f); p15card->tokeninfo->manufacturer_id = strdup("TeleSec GmbH"); p15card->tokeninfo->label = strdup(card->type==SC_CARD_TYPE_TCOS_V3 ? "NetKey V3 Card" : "NetKey Card"); keylen= card->type==SC_CARD_TYPE_TCOS_V3 ? 2048 : 1024; c_auth= card->type==SC_CARD_TYPE_TCOS_V3 ? "C500" : "C100"; insert_cert(p15card, dirpath(dir,"4331"), 0x45, 1, "Signatur Zertifikat 1"); insert_cert(p15card, dirpath(dir,"4332"), 0x45, 1, "Signatur Zertifikat 2"); insert_cert(p15card, dirpath(dir,"C000"), 0x45, 0, "Telesec Signatur Zertifikat"); insert_cert(p15card, dirpath(dir,"43B1"), 0x46, 1, "Verschluesselungs Zertifikat 1"); insert_cert(p15card, dirpath(dir,"43B2"), 0x46, 1, "Verschluesselungs Zertifikat 2"); insert_cert(p15card, dirpath(dir,"C200"), 0x46, 0, "Telesec Verschluesselungs Zertifikat"); insert_cert(p15card, dirpath(dir,"4371"), 0x47, 1, "Authentifizierungs Zertifikat 1"); insert_cert(p15card, dirpath(dir,"4372"), 0x47, 1, "Authentifizierungs Zertifikat 2"); insert_cert(p15card, dirpath(dir,c_auth), 0x47, 0, "Telesec Authentifizierungs Zertifikat"); insert_cert(p15card, dirpath(dir,"C201"), 0x48, 0, "Telesec 1024bit Zertifikat"); insert_key(p15card, dirpath(dir,"5331"), 0x45, 0x80, keylen, 4, "Signatur Schluessel"); insert_key(p15card, dirpath(dir,"53B1"), 0x46, 0x81, keylen, 3, "Verschluesselungs Schluessel"); insert_key(p15card, dirpath(dir,"5371"), 0x47, 0x82, keylen, 3, "Authentifizierungs Schluessel"); insert_key(p15card, dirpath(dir,"0000"), 0x48, 0x83, 1024, 3, "1024bit Schluessel"); insert_pin(p15card, "5000", 1, 2, 0x00, 6, "PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED ); insert_pin(p15card, "5001", 2, 0, 0x01, 8, "PUK", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN ); if(card->type==SC_CARD_TYPE_TCOS_V3){ insert_pin(p15card, dirpath(dir,"0000"), 3, 1, 0x83, 6, "NetKey PIN2", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); } else { insert_pin(p15card, dirpath(dir,"5080"), 3, 1, 0x80, 6, "NetKey PIN0", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); } insert_pin(p15card, dirpath(dir,"5081"), 4, 1, 0x81, 6, "NetKey PIN1", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); /* SigG-Applikation */ p.len=7; p.type=SC_PATH_TYPE_DF_NAME; memcpy(p.value, "\xD2\x76\x00\x00\x66\x01", p.len=6); if (sc_select_file(card,&p,&f)==SC_SUCCESS){ sprintf(dir,"%04X", f->id); sc_file_free(f); insert_cert(p15card, dirpath(dir,"C000"), 0x49, 1, "SigG Zertifikat 1"); insert_cert(p15card, dirpath(dir,"4331"), 0x49, 1, "SigG Zertifikat 2"); insert_cert(p15card, dirpath(dir,"4332"), 0x49, 1, "SigG Zertifikat 3"); if(card->type==SC_CARD_TYPE_TCOS_V3){ insert_key(p15card, dirpath(dir,"0000"), 0x49, 0x84, 2048, 5, "SigG Schluessel"); } else { insert_key(p15card, dirpath(dir,"5331"), 0x49, 0x80, 1024, 5, "SigG Schluessel"); } insert_pin(p15card, dirpath(dir,"5081"), 5, 0, 0x81, 6, "SigG PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); if(card->type==SC_CARD_TYPE_TCOS_V3){ insert_pin(p15card, dirpath(dir,"0000"), 6, 0, 0x83, 8, "SigG PIN2", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED ); } } return 0; }
static int archive(const char *filename, int arglen, char *args[]) { xar_t x; FTS *fts; FTSENT *ent; int flags; struct lnode *i; const char *default_compression; x = xar_open(filename, WRITE); if( !x ) { fprintf(stderr, "Error creating archive %s\n", filename); exit(1); } if ( SigSize ) { xar_signature_t sig = xar_signature_new(x, "RSA", SigSize, &signingCallback, NULL); if ( LeafCertPath ) insert_cert(sig, LeafCertPath); if ( IntermediateCertPath ) insert_cert(sig, IntermediateCertPath); } if( Toccksum ) xar_opt_set(x, XAR_OPT_TOCCKSUM, Toccksum); if( Compression ) xar_opt_set(x, XAR_OPT_COMPRESSION, Compression); if( Coalesce ) xar_opt_set(x, XAR_OPT_COALESCE, "true"); if( LinkSame ) xar_opt_set(x, XAR_OPT_LINKSAME, "true"); if ( Rsize != NULL ) xar_opt_set(x, XAR_OPT_RSIZE, Rsize); xar_register_errhandler(x, err_callback, NULL); if( Subdoc ) add_subdoc(x); if( Perms == SYMBOLIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC); } if( Perms == NUMERIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC); } default_compression = strdup(xar_opt_get(x, XAR_OPT_COMPRESSION)); if( !default_compression ) default_compression = strdup(XAR_OPT_VAL_GZIP); flags = FTS_PHYSICAL|FTS_NOSTAT|FTS_NOCHDIR; if( Local ) flags |= FTS_XDEV; fts = fts_open(args, flags, NULL); if( !fts ) { fprintf(stderr, "Error traversing file tree\n"); exit(1); } while( (ent = fts_read(fts)) ) { xar_file_t f; int exclude_match = 1; int nocompress_match = 1; if( ent->fts_info == FTS_DP ) continue; if( strcmp(ent->fts_path, "/") == 0 ) continue; if( strcmp(ent->fts_path, ".") == 0 ) continue; for( i = Exclude; i; i=i->next ) { exclude_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0); if( !exclude_match ) break; } if( !exclude_match ) { if( Verbose ) printf("Excluding %s\n", ent->fts_path); continue; } for( i = NoCompress; i; i=i->next ) { nocompress_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0); if( !nocompress_match ) { xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE); break; } } f = xar_add(x, ent->fts_path); if( !f ) { fprintf(stderr, "Error adding file %s\n", ent->fts_path); } else { print_file(f); } if( !nocompress_match ) xar_opt_set(x, XAR_OPT_COMPRESSION, default_compression); } fts_close(fts); if( xar_close(x) != 0 ) { fprintf(stderr, "Error creating the archive\n"); if( !Err ) Err = 42; } free((char *)default_compression); for( i = Exclude; i; ) { struct lnode *tmp; regfree(&i->reg); tmp = i; i = i->next; free(tmp); } for( i = NoCompress; i; ) { struct lnode *tmp; regfree(&i->reg); tmp = i; i = i->next; free(tmp); } if ( SigOffsetDumpPath ) { x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error re-opening archive %s\n", filename); exit(1); } if (extract_sig_offset(x, SigOffsetDumpPath)) exit(1); } return Err; }
/* replace_sign: rip out all current signatures and certs and insert a new pair Since libxar is currently not capable of doing this directly, we have to create a new xar archive, copy all the files and options from the current archive, and sign the new archive */ static void replace_sign(const char *filename) { xar_t old_xar, new_xar; xar_signature_t sig; char *new_xar_path = (char *)malloc(15); strncpy(new_xar_path, "/tmp/xar.XXXXX", 15); new_xar_path = mktemp(new_xar_path); char *systemcall; int err; // open both archives old_xar = xar_open(filename, READ); if ( old_xar == NULL ) { fprintf(stderr, "Could not open archive %s!\n", filename); exit(1); } new_xar = xar_open(new_xar_path, WRITE); if( !new_xar ) { fprintf(stderr, "Error creating new archive %s\n", new_xar_path); exit(1); } // install new signature and new certs in new_xar sig = xar_signature_new(new_xar, "RSA", SigSize, &signingCallback, NULL); if ( LeafCertPath ) insert_cert(sig, LeafCertPath); if ( IntermediateCertPath ) insert_cert(sig, IntermediateCertPath); // copy options char *opts[6] = {XAR_OPT_TOCCKSUM, XAR_OPT_COMPRESSION, XAR_OPT_COALESCE, XAR_OPT_LINKSAME, XAR_OPT_RSIZE, XAR_OPT_OWNERSHIP}; int i; const char *opt; for (i=0; i<6; i++) { opt = xar_opt_get(old_xar, opts[i]); if (opt) xar_opt_set(new_xar, opts[i], opt); } // skip copy subdocs for now since we don't use them yet // copy files xar_iter_t iter = xar_iter_new(); xar_file_t f = xar_file_first(old_xar, iter); // xar_file_next iterates the archive depth-first, i.e. all children are enumerated before the siblings. const char *name; char *f_dirname, *stack_top_dirname; stack s_new = stack_new(); stack s_old = stack_new(); xar_file_t last_copied = NULL, last_added; xar_iter_t loopIter = xar_iter_new(); xar_file_t current_xar_file; for (current_xar_file = xar_file_first(old_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter)) { printf("old_xar -> %s (parent: %s)\n",xar_get_path(current_xar_file),XAR_FILE(current_xar_file)->parent?xar_get_path(XAR_FILE(current_xar_file)->parent):"(nil)"); } do { // parent is the parent in the new archive! // 3 cases: // 1. the file has no parent. Happens for every file at the top level of the archive. // 2. the file's parent is the last file we added. Happens while descending down a path // 3. the file's parent is one of the ancestors of the last file (and not NULL, that would be case 1) // that means we either go back up the tree and add a sibling of one of the ancestors, or we add a // sibling on the same level xar_prop_get(f, "name", &name); // filename, without any path info if (!XAR_FILE(f)->parent) { // case 1 printf("root: %s\n",xar_get_path(f)); last_added = xar_add_from_archive(new_xar, NULL, name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } else if (f->parent == last_copied) { // case 2 printf("child: %s -> %s\n",xar_get_path(f->parent),xar_get_path(f)); last_added = xar_add_from_archive(new_xar, last_added, name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } else { // case 3 printf("searching for parent: %s ?\n",xar_get_path(f)); while (XAR_FILE(f)->parent != XAR_FILE(s_old->top->data)->parent) { printf("popping: %s\n",xar_get_path(XAR_FILE(s_old->top->data))); stack_pop(s_new); stack_pop(s_old); } printf("found: %s -> %s\n",xar_get_path(XAR_FILE(s_new->top->data)),xar_get_path(f)); stack_pop(s_new); stack_pop(s_old); last_added = xar_add_from_archive(new_xar, (xar_file_t)(s_new->top->data), name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } } while (f = xar_file_next(iter)); loopIter = xar_iter_new(); for (current_xar_file = xar_file_first(new_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter)) { char * current_path = xar_get_path(current_xar_file); printf("new_xar -> %s\n",current_path); } xar_iter_free(iter); stack_free(s_new); stack_free(s_old); if( xar_close(new_xar) != 0 ) { fprintf(stderr, "Error creating the archive\n"); if( !Err ) Err = 42; } xar_close(old_xar); // write signature offset to file (have to re-open so xar_close can figure out the correct offset) new_xar = xar_open(new_xar_path, READ); if( !new_xar ) { fprintf(stderr, "Error re-opening new archive %s\n", new_xar_path); unlink(new_xar_path); exit(1); } if (extract_sig_offset(new_xar, SigOffsetDumpPath)) { xar_close(new_xar); unlink(new_xar_path); exit(1); } xar_close(new_xar); // delete old archive, move new in its place unlink(filename); asprintf(&systemcall, "cp \"%s\" \"%s\"", new_xar_path, filename); err = system(systemcall); if (err) { fprintf(stderr, "Could not copy new archive to final location (system() returned %i)\n", err); unlink(new_xar_path); exit(1); } // Delete the tmp archive unlink(new_xar_path); free(systemcall); }