Hej! Jag har experimenterat lite med att importera den PKCS#12-fil som skapats av FriBID till ett smartkort (i mitt fall en med SafeSign-appleten) och sedan försökt använda kortet med FriBID.
Se bifogad guide howto-fribid-p12-to-smartcard.txt. Eftersom mitt kort bara har stöd för en PKCS#11 slot så försökte jag lägga både authentiserings- och signerings-certen (+nycklar) på samma slot men det visade sig att FriBID inte stödde detta. Det var även problem om kortet innehöll andra certifikat före de från BankID. Den bifogade patchen multiple-certs-in-slot-1.patch är tänkt att lösa dessa problem genom att inte avbryta om ett okänt certifikat påträffats utan istället fortsätta och kontrollera övriga och lägga till alla som matchar samt att det valda certifikatet sedan används istället för alltid det första. Mvh Markus Kilås
>From c64e28e3ead0947fd053d514f0dbab58bdda0da3 Mon Sep 17 00:00:00 2001 From: Markus Kilås <[email protected]> Date: Jun 4, 2012 8:32:36 AM Support for multiple certificates and key-pairs in the same PKCS#11 slot. diff --git a/client/pkcs11.c b/client/pkcs11.c index df49969..42e6744 100644 --- a/client/pkcs11.c +++ b/client/pkcs11.c @@ -52,6 +52,7 @@ struct PKCS11Token { Token base; PKCS11_SLOT *slot; + PKCS11_CERT *cert; PKCS11_CERT *certs; unsigned int ncerts; }; @@ -89,7 +90,7 @@ static TokenError _backend_getBase64Chain(const PKCS11Token *token, char ***certs, size_t *count) { - X509 *cert = token->certs[0].x509; + X509 *cert = token->cert[0].x509; if (!cert) { return TokenError_Unknown; } @@ -133,7 +134,7 @@ } // Find the key for the token - PKCS11_CERT *cert = &token->certs[0]; + PKCS11_CERT *cert = token->cert; PKCS11_KEY *key = PKCS11_find_key(cert); if (!key) return TokenError_BadPin; @@ -159,40 +160,46 @@ */ static void pkcs11_found_token(Backend *backend, PKCS11_SLOT *slot) { int rc; - - PKCS11Token *token = calloc(1, sizeof(PKCS11Token)); - if (!token) return; - - token->slot = slot; // Scan card - rc = PKCS11_enumerate_certs(slot->token, &token->certs, &token->ncerts); - if (rc || token->ncerts == 0) - goto fail; - - // Firts cert in the chain is the user cert. Rest is associated authority certs - X509 *x = token->certs[0].x509; - X509_NAME *id = X509_get_subject_name(x); - - if (!certutil_hasKeyUsage(x, backend->notifier->keyUsage)) - goto fail; - - if (!certutil_matchSubjectFilter(backend->notifier->subjectFilter, id)) - goto fail; - - token->base.backend = backend; - if (slot->token->secureLogin == 0) { - token->base.status = TokenStatus_NeedPassword; - } else { - token->base.status = TokenStatus_NeedPIN; + unsigned int ncerts = 0; + PKCS11_CERT *certs; + rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); + if (rc || ncerts == 0) { + fprintf(stderr, BINNAME ": found no certificates in slot\n"); + return; } - token->base.displayName = certutil_getDisplayNameFromDN(id); - token->base.tag = slot->token->label; - backend->notifier->notifyFunction(&token->base, TokenChange_Added); - return; -fail: - backend->freeToken(token); + for (unsigned int i = 0; i < ncerts; i++) { + // Check if this certificate is a BankID and has the right key usage + X509 *x = certs[i].x509; + X509_NAME *id = X509_get_subject_name(x); + + if (!certutil_hasKeyUsage(x, backend->notifier->keyUsage)) + continue; + + if (!certutil_matchSubjectFilter(backend->notifier->subjectFilter, id)) + continue; + + PKCS11Token *token = calloc(1, sizeof(PKCS11Token)); + if (!token) return; + + token->slot = slot; + token->cert = &certs[i]; + token->certs = certs; + token->ncerts = ncerts; + + token->base.backend = backend; + if (slot->token->secureLogin == 0) { + token->base.status = TokenStatus_NeedPassword; + } else { + token->base.status = TokenStatus_NeedPIN; + } + token->base.displayName = certutil_getDisplayNameFromDN(id); + token->base.tag = slot->token->label; + backend->notifier->notifyFunction(&token->base, TokenChange_Added); + } + } /**
Fribid p12 to smartcard ----------------------- The format of the PKCS#12 file produced by Fribid is not compatible with Java which I will be using to import the keys and certificates to the smart card so we will first have to create a new PKCS#12 using OpenSSL. Notice: Fribid expects different slots for the auth and sign key-pairs/certificates so a patch is required for the below setup with both certificates in the same slot. 1. Use OpenSSL to "import" the PKCS#12 file openssl pkcs12 -nomacver -in "(110327 13.37) MY NAME - BankID på fil.p12" -out myname-bankid-auth.pem 2. Make a copy of myname-bankid-sign.pem cp myname-bankid-auth.pem myname-bankid-sign.pem 3. Open and edit myname-bankid-auth.pem so that it only contains the first private key and the authentication certificate and the CA certificates nano myname-bankid-auth.pem 4. Open and edit myname-bankid-sign.pem so that it only contains the second private key and the signature certificate and the CA certificates nano myname-bankid-sign.pem 5. Use OpenSSL to "export" them to new PKCS#12 files openssl pkcs12 -export -in myname-bankid-auth.pem -out myname-bankid-auth.p12 -name "myname-bankid-auth" openssl pkcs12 -export -in myname-bankid-sign.pem -out myname-bankid-sign.p12 -name "myname-bankid-sign" 3. Create a SunPkcs11 config file pointing out the PKCS#11 module. For SafeSign the following works: name=SafeSign library=/usr/lib/libaetpkss.so slotListIndex = 0 4. Use Java Keytool to import the keystores to the card keytool -importkeystore -srckeystore myname-bankid-auth.p12 -srcstoretype pkcs12 -destkeystore NONE -deststoretype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg sunp11-safesign.conf keytool -importkeystore -srckeystore myname-bankid-sign.p12 -srcstoretype pkcs12 -destkeystore NONE -deststoretype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg sunp11-safesign.conf 5. Use Java Keytool to see that both entris are available and with the certificate chains keytool -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg sunp11-safesign.conf -list -v 6. Configure FriBid to use the SafeSign PKCS#11 module by adding the following to ~/.config/fribid/config [pkcs11] module=/usr/lib/libaetpkss.so
