From: 建明 <jia...@12...> - 2015-04-03 06:26:11
|
Hello, guys I'm new to this community and forgive me if I ask something wrong. In the past month, I managed to configuring smart card to do authentication on ubuntu12.04.5 x86 I find some problems with pam_pkcs11-0.6.7, which is the version used by ubuntu 12.04. I) problem I I installed three certificates on the smart card,among which, only the last one is the correct one. The pam_sm_authenticate() checks the certificates one by one in a loop . However, when verify_certificate() checks the second one and returns -4, the loop breaks. so the last certificate even has no chance to be checked. As the red colour in the code, it should not break the loop in this case. And if change the "break" to "continue", the issue is fixed. pam_sm_authenticate() { for (i = 0; i < ncert; i++) { rv = verify_certificate(x509,&configuration->policy); if (rv < 0) { ERR1("verify_certificate() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "verify_certificate() failed: %s", get_error()); switch (rv) { case -2: // X509_V_ERR_CERT_HAS_EXPIRED: snprintf(password_prompt, sizeof(password_prompt), _("Error 2324: Certificate has expired")); break; case -3: // X509_V_ERR_CERT_NOT_YET_VALID: snprintf(password_prompt, sizeof(password_prompt), _("Error 2326: Certificate not yet valid")); break; case -4: // X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: snprintf(password_prompt, sizeof(password_prompt), _("Error 2328: Certificate signature invalid")); break; default: snprintf(password_prompt, sizeof(password_prompt), _("Error 2330: Certificate invalid")); break; } }//for }//function II) verify_signature() of a correct certificate from smart card reports error like the red colour. I create the certificate using a windows 2008 server Certificate agent by some standard way as illustrated at the end of the email. I believe the certificate format should be right. and I don't know why the library complains . DEBUG:pkcs11_lib.c:1450: closing the PKCS #11 session DEBUG:pkcs11_lib.c:1456: releasing keys and certificates ERROR:pam_pkcs11.c:728: verify_signature() failed: EVP_VerifyFinal() failed: error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01 Error 2342: Verifying signature failed III) It only supports 128 bytes key length, this is hard coded like this. int sign_value(pkcs11_handle_t *h, cert_object_t *cert, CK_BYTE *data, CK_ULONG length, CK_BYTE **signature, CK_ULONG *signature_length) { *signature_length = 128; } However, in real life, 2048bits key length is commonly used. Any reply or comments are appreciated. thank everyone in advance. Best regards Jianming Appended is the detailed instructions on configuring pam on ubuntu. Configure Linux smartcard authentication Getting started The following instructions are verified on Ubuntu12.04 32bits on x86 arch. The smartcard is Gemalto.net v2. PIV smartcard is not verified, so i don't know whether it works. Writing the certificate into the smartcard I tried self-signed certificate into the smartcard for authentication with no luck. Maybe this's worth more investigation. If self signed certificate doesn't works for pam-pkcs11, it's suggested that you setup the certificate in the windows domain with AD (active directory service)and CA (certificate agent service). create AD service on windows 2008 server. Then join the ubuntu machine into the AD sudo apt-get install likewise-open sudo domainjoin-cli join DomainFQN DomainAcount reboot After setup , try the following command with success. su DomainAccount@DomainFQN Install CA service on the AD server, and writing the certificate into the smart card The document includes detailed step-by-step instruction on how to issue the certificate and enroll the certificate into the smart card. http://henrysluiman.blogspot.hk/2011/12/installing-windows-2008-r2-certificate.html It's rather tedious steps that torture you patience. However after some trial, you will make it. Note: in this step, Pay special attention that the public key length should be 1024 bits rather then 2048 bits , since the linux pam-pkcs11 lib only supports 1024 bits key length. Export the CA root certificate and save it in a file like certnew.pem By default , the exported certificate is .cer file,which is in binary format. However, the Linux Pam expects PEM , which is ASCII format. You need to convert the .cert file into .PEM file. I do this by some workaround. I copy the file into my Mac book, click it in mac book, and there is option to do the conversion. Setup the software on the ubuntu machine libpam-pkcs11 This is a plugin to linux PAM subsystem. It instructs PAM how to use smart card to do the authentication. In practise, there is some problem with this lib, and we need to make some workaround to the source code before move on.After compile the source code, replace the lib to /lib/security/pam_pkcs11.s0. pcscd libpcsclite1 The underlying library to initiate r/w to the smart card user reader. libgemaltodonentp11.deb The vendor's implementation of pkcs#11 spec, which instructs how to interpret with the data from smart card. pcsc-tools Optional. It provides pcsc_scan tools to communicate with the smart card hardware, by passing the pkcs#11 spec. This is used to verify whether the physical layer of smart card works. opensc This is optional. it includes pkcs11-tool which can be used to r/w object from/to the smart card. To verify the card setup ok, execute pkcs11-tool --module /usr/lib/libgtop11dotnet.so -I -p 0000 -O -L Config the PAM software. Document online illustrates how to configure the PAM to do smart card login. However, seems it's some old and need some modification. http://ubuntuforums.org/showthread.php?t=1557180#2 These are verified steps based on it. sudo mkdir -p /etc/pam_pkcs11/cacerts /etc/pam_pkcs11/crls /etc/pam_pkcs11/cacerts is where the CA root certificate certnew.pem is stored. /etc/pam_pkcs11/crls is of no interest currently. modify the pam pkcs11 conf file zcat /usr/share/doc/libpam-pkcs11/examples/pam_pkcs11.conf.example.example.gz | sudo tee /etc/pam_pkcs11/pam_pkcs11.conf The key is modify ca_dir in the config file to the path name of CA root certificate file pkcs11_module opensc { module = /usr/lib/libgtop11dotnet.so; description = "OpenSC PKCS#11 module"; .... ca_dir = /etc/pam_pkcs11/cacerts/viewconnection-jianming-CA.pem; Modify the pam-pkcs11.so source code This seems some problems with pam-pkcs11.so, you need to make some workarounds before moving on. Don't exit the loop when meet one wrong certificate, continue to pick another one. if (rv < 0) { ERR1("verify_certificate() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "verify_certificate() failed: %s", get_error()); switch (rv) { case -2: // X509_V_ERR_CERT_HAS_EXPIRED: snprintf(password_prompt, sizeof(password_prompt), _("Error 2324: Certificate has expired")); break; case -3: // X509_V_ERR_CERT_NOT_YET_VALID: snprintf(password_prompt, sizeof(password_prompt), _("Error 2326: Certificate not yet valid")); break; case -4: // X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: snprintf(password_prompt, sizeof(password_prompt), _("Error 2328: Certificate signature invalid")); continue default: snprintf(password_prompt, sizeof(password_prompt), _("Error 2330: Certificate invalid")); break; } padding format verification failed. In file pam_pkcs11-0.6.7/src/common/cert_vfy.c EVP_VerifyInit(&md_ctx, EVP_sha1()); EVP_VerifyUpdate(&md_ctx, data, data_length); rv = EVP_VerifyFinal(&md_ctx, signature, signature_length, pubkey); EVP_PKEY_free(pubkey); if (rv != 1) { set_error("EVP_VerifyFinal() failed: %s", ERR_error_string(ERR_get_error(), NULL)); // return -1 } It only supports 128 bytes key length. so remember this restriction when creating and signing the certificate. int sign_value(pkcs11_handle_t *h, cert_object_t *cert, CK_BYTE *data, CK_ULONG length, CK_BYTE **signature, CK_ULONG *signature_length) { *signature_length = 128; } modify the pam conf file Take su command as example. Add one line to the beginning of /etc/pam.d/su auth sufficient pam_pkcs11.so Verification After all the previous steps, execute the command to test whether it works. su DomainAccount@DomainFQN The command will prompts user for smartcard pin. After input Pin , the autentication succeeds Many thanks |