/* * Authenticate with the card. relogin should be set if we automatically * relogin after a fork. */ static int pkcs11_login(PKCS11_SLOT * slot, int so, const char *pin, int relogin) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = priv->parent; int rv; if (relogin == 0) { CHECK_SLOT_FORK(slot); /* Calling PKCS11_login invalidates all cached * keys we have */ if (slot->token) { pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY); pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY); } if (priv->loggedIn) { /* already logged in, log out first */ if (PKCS11_logout(slot)) return -1; } } if (!priv->haveSession) { /* SO gets a r/w session by default, * user gets a r/o session by default. */ if (pkcs11_open_session(slot, so, relogin)) return -1; } rv = CRYPTOKI_call(ctx, C_Login(priv->session, so ? CKU_SO : CKU_USER, (CK_UTF8CHAR *) pin, pin ? strlen(pin) : 0)); if (rv && rv != CKR_USER_ALREADY_LOGGED_IN) /* logged in -> OK */ CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGIN, rv); priv->loggedIn = 1; if (priv->prev_pin != pin) { if (priv->prev_pin) { OPENSSL_cleanse(priv->prev_pin, strlen(priv->prev_pin)); OPENSSL_free(priv->prev_pin); } priv->prev_pin = BUF_strdup(pin); } priv->prev_so = so; return 0; }
ByteArray SmartcardSlot::decrypt(std::string &keyId, std::string &pin, ByteArray &data) throw (SmartcardModuleException) { int rc, found = 0, nret, keySize, j, errorCode; PKCS11_KEY *keys; ByteArray ret; unsigned int nKeys, i; std::string idTmp; char *bufferId; ERR_clear_error(); if (pin.size() < 4 || pin.size() > 8) { throw SmartcardModuleException(SmartcardModuleException::INVALID_PIN, "SmartcardSlot::decrypt", true); } rc = PKCS11_login(this->slot, 0, pin.c_str()); if (rc != 0) { errorCode = ERR_GET_REASON(ERR_get_error()); if (errorCode == SmartcardModuleException::BLOCKED_PIN) { throw SmartcardModuleException(SmartcardModuleException::BLOCKED_PIN, "SmartcardSlot::decrypt", true); } else if (errorCode == SmartcardModuleException::INVALID_PIN) { throw SmartcardModuleException(SmartcardModuleException::INVALID_PIN, "SmartcardSlot::decrypt", true); } else { throw SmartcardModuleException(SmartcardModuleException::UNKNOWN, "SmartcardSlot::decrypt", true); } } rc = PKCS11_enumerate_keys(this->slot[0].token, &keys, &nKeys); if (rc != 0 || nKeys == 0) { PKCS11_logout(this->slot); throw SmartcardModuleException(SmartcardModuleException::ENUMERATING_PRIVATE_KEYS, "SmartcardSlot::decrypt", true); } found = -1; for (i=0;(i<nKeys)&&(found==-1);i++) { bufferId = (char *)calloc((keys[i].id_len * 2) + 1, sizeof(char)); for (j=0;j<keys[i].id_len;j++) { sprintf(&(bufferId[j*2]), "%02X", keys[i].id[j]); } idTmp = bufferId; free(bufferId); if (keyId == idTmp) { found = i; keySize = PKCS11_get_key_size(&keys[i]); } } if (found < 0) { PKCS11_logout(this->slot); //TODO: apagar todas as chaves encontradas, não tem na libp11 throw SmartcardModuleException(SmartcardModuleException::ID_NOT_FOUND, "SmartcardSlot::decrypt", true); } ret = ByteArray(keySize); nret = PKCS11_private_decrypt(data.size(), data.getDataPointer(), ret.getDataPointer(), &keys[found], RSA_PKCS1_PADDING); PKCS11_logout(this->slot); if (nret <= 0) { throw SmartcardModuleException(SmartcardModuleException::DECRYPTING_DATA, "SmartcardSlot::decrypt", true); } ret = ByteArray(ret.getDataPointer(), nret); return ret; }
static int tap11_store_cert( const char *libp11, const char *pin, const char *certid, const char *certfile) { int rc; unsigned int nslots; PKCS11_CTX *p11ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *cert; X509 *x509; BIO *bio; p11ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(p11ctx,libp11); if (rc) { fprintf(stderr,"PKCS11_CTX_load\n"); return -1; } /* get information on all slots */ rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr,"PKCS11_enumerate_slots\n"); return -1; } /* get first slot with a token */ slot = PKCS11_find_token(p11ctx, slots, nslots); if (!slot || !slot->token) { fprintf(stderr,"PKCS11_find_token\n"); return -1; } fprintf(stderr,"Slot manufacturer......: %s\n", slot->manufacturer); fprintf(stderr,"Slot description.......: %s\n", slot->description); fprintf(stderr,"Slot token label.......: %s\n", slot->token->label); fprintf(stderr,"Slot token manufacturer: %s\n", slot->token->manufacturer); fprintf(stderr,"Slot token model.......: %s\n", slot->token->model); fprintf(stderr,"Slot token serialnr....: %s\n", slot->token->serialnr); rc = PKCS11_open_session(slot, 1); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_open_session %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } rc = PKCS11_login(slot, 0, pin); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_login %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } /* load cert */ if ((bio = BIO_new(BIO_s_file())) == NULL) { fprintf(stderr,"BIO_new\n"); return -1; } if (BIO_read_filename(bio,certfile) <= 0) { fprintf(stderr,"BIO_read_filename\n"); return -1; } x509 = PEM_read_bio_X509_AUX(bio,NULL, NULL, NULL); if (x509 == NULL) { fprintf(stderr,"PKCS11_enumerate_certs\n"); return -1; } /* store cert */ rc = PKCS11_store_certificate(slot->token,x509, (char*)certid,(unsigned char*)certid,strlen(certid),&cert); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_store_certificate %s rc:%d\n", ERR_reason_error_string(ERR_get_error()),rc); return -1; } X509_free(x509); BIO_free(bio); PKCS11_logout(slot); PKCS11_release_all_slots(p11ctx, slots, nslots); PKCS11_CTX_unload(p11ctx); PKCS11_CTX_free(p11ctx); fprintf(stderr,"\n\nstore cert succeed\n"); return 0; }
static int tap11_change_pin( const char *p11lib, int is_so, const char *pin, const char *newpin) { int rc = 0; unsigned int nslots; PKCS11_CTX *p11ctx; PKCS11_SLOT *slots, *slot; p11ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(p11ctx,p11lib); if (rc) { fprintf(stderr,"PKCS11_CTX_load\n"); return -1; } /* get information on all slots */ rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr,"PKCS11_enumerate_slots\n"); return -1; } /* get first slot with a token */ slot = PKCS11_find_token(p11ctx, slots, nslots); if (!slot || !slot->token) { fprintf(stderr,"PKCS11_find_token\n"); return -1; } fprintf(stderr,"Slot manufacturer......: %s\n", slot->manufacturer); fprintf(stderr,"Slot description.......: %s\n", slot->description); fprintf(stderr,"Slot token label.......: %s\n", slot->token->label); fprintf(stderr,"Slot token manufacturer: %s\n", slot->token->manufacturer); fprintf(stderr,"Slot token model.......: %s\n", slot->token->model); fprintf(stderr,"Slot token serialnr....: %s\n", slot->token->serialnr); /* rw mode */ rc = PKCS11_open_session(slot, 1); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_open_session %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } rc = PKCS11_login(slot, is_so, pin); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_init_login %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } rc = PKCS11_change_pin(slot,pin,newpin); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_change_pin %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } PKCS11_logout(slot); PKCS11_release_all_slots(p11ctx, slots, nslots); PKCS11_CTX_unload(p11ctx); PKCS11_CTX_free(p11ctx); fprintf(stderr,"\n\npin change succeed\n"); return 0; }
static Bool LoadEnginePKCS11(SSL_CTX *ctx, ENGINE **e, const char *p11lib, const char *slotstr) { char certid[PKCS11_BUF_SIZE]; char certidbuf[PKCS11_BUF_SIZE]; char pinbuf[PKCS11_BUF_SIZE]; char *pin = NULL; EVP_PKEY *key = NULL; X509 *x509 = NULL; int rc = 0; int i; unsigned int nslots,ncerts; int nslot = 0; PKCS11_CTX *p11ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *certs,*cert; pin = GetPasswordString(pinbuf, sizeof(pinbuf), PKCS11_ASKPIN_PROMPT); if (pin == NULL){ Message("PIN input was canceled\n"); return FALSE; } p11ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(p11ctx, p11lib); if (rc) { SSL_Error("loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); return FALSE; } /* get information on all slots */ rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots); if (rc < 0) { SSL_Error("no slots available\n"); return FALSE; } /* get certificate and keyid by PKCS#11 */ if (strcmp("",slotstr)){ nslot = atoi(slotstr); if (nslot < nslots) { slot = (PKCS11_SLOT*)&slots[nslot]; if (!slot || !slot->token) { SSL_Error("no token available\n"); return FALSE; } } else { SSL_Error("no token available\n"); return FALSE; } } else { /* get first slot with a token */ slot = PKCS11_find_token(p11ctx, slots, nslots); if (!slot || !slot->token) { SSL_Error("no token available\n"); return FALSE; } for(i=0;i<nslots;i++) { if (&slots[i] == slot) { nslot = i; } } } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, pin); if (rc != 0) { SSL_Error("PKCS11_login failed\n"); return FALSE; } /* get all certs */ rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); if (rc) { SSL_Error("PKCS11_enumerate_certs failed\n"); return FALSE; } if (ncerts <= 0) { SSL_Error("no certificates found\n"); return FALSE; } /* use the first cert */ cert=(PKCS11_CERT*)&certs[0]; sprintf(certid,"slot_%d-id_",nslot); for(i=0;i<cert->id_len;i++) { sprintf(certidbuf,"%02x",(unsigned int)(cert->id[i])); strcat(certid,certidbuf); } printf("id:[%s] label:%s [%p]\n",certid,cert->label,cert->x509); x509 = X509_dup(cert->x509); PKCS11_logout(slot); PKCS11_release_all_slots(p11ctx, slots, nslots); PKCS11_CTX_unload(p11ctx); PKCS11_CTX_free(p11ctx); /* setup OpenSSL ENGINE */ if (!(*e = InitEnginePKCS11(p11lib, pin))){ return FALSE; } if(!(key = ENGINE_load_private_key(*e, certid, NULL, NULL))) { SSL_Error(_d("ENGINE_load_private_key failure:\n %s\n"), GetSSLErrorString()); return FALSE; } /* set key and cert to SSL_CTX */ if (key){ if (!SSL_CTX_use_certificate_with_check(ctx, x509)){ SSL_Error(_d("SSL_CTX_use_certificate failure:\n %s"), GetSSLErrorString()); return FALSE; } if (!SSL_CTX_use_PrivateKey(ctx, key)){ SSL_Error(_d("SSL_CTX_use_PrivateKey failure:\n %s"), GetSSLErrorString()); return FALSE; } if (!SSL_CTX_check_private_key(ctx)){ SSL_Error(_d("SSL_CTX_check_private_key failure:\n %s\n"), GetSSLErrorString()); return FALSE; } } memset(pin, 0, sizeof(pinbuf)); return TRUE; }