/** * Implements signing certificate selector for EstEID ID-Cards. * * @param certificates list of certificates to choose from. List of all certificates * found ID-card. * @return should return the selected certificate. * @throws SignException throws exception if no suitable certificate was found. */ digidoc::PKCS11Signer::PKCS11Cert digidoc::EstEIDSigner::selectSigningCertificate( const std::vector<PKCS11Signer::PKCS11Cert> &certificates) const throw(SignException) { // Find EstEID signing certificate if(certificates.empty()) THROW_SIGNEXCEPTION("Could not find certificate."); for(std::vector<PKCS11Signer::PKCS11Cert>::const_iterator i = certificates.begin(); i < certificates.end(); ++i) { ASN1_BIT_STRING *keyusage = (ASN1_BIT_STRING*)X509_get_ext_d2i(i->cert, NID_key_usage, 0, 0); if(!keyusage) continue; for(int n = 0; n < 9; ++n) { if(ASN1_BIT_STRING_get_bit(keyusage, n) && n == 1) { ASN1_BIT_STRING_free( keyusage ); return *i; } } ASN1_BIT_STRING_free( keyusage ); } THROW_SIGNEXCEPTION("Could not find certificate."); return PKCS11Signer::PKCS11Cert(); }
static VALUE decode_bstr(unsigned char* der, int length, long *unused_bits) { ASN1_BIT_STRING *bstr; unsigned char *p, *buf; long len; VALUE ret; p = der; if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) ossl_raise(eASN1Error, NULL); len = bstr->length; if(!(buf = OPENSSL_malloc(len))){ ASN1_BIT_STRING_free(bstr); ossl_raise(eASN1Error, NULL); } *unused_bits = 0; if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT) *unused_bits = bstr->flags & 0x07; memcpy(buf, bstr->data, len); ASN1_BIT_STRING_free(bstr); ret = ossl_buf2str(buf, len); return ret; }
static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; unsigned char *buf=NULL,*databuf,*sptr; int i,j,data_len,ret=0; int ptype = V_ASN1_UNDEF; DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); if (pk->save_parameters) { ASN1_STRING *params = encode_gost_algor_params(pk); pval = params; ptype = V_ASN1_SEQUENCE; } data_len = BN_num_bytes(dsa->pub_key); databuf = OPENSSL_malloc(data_len); BN_bn2bin(dsa->pub_key,databuf); octet = ASN1_OCTET_STRING_new(); ASN1_STRING_set(octet,NULL,data_len); sptr = ASN1_STRING_data(octet); for (i=0,j=data_len-1; i< data_len;i++,j--) { sptr[i]=databuf[j]; } OPENSSL_free(databuf); ret = i2d_ASN1_OCTET_STRING(octet,&buf); ASN1_BIT_STRING_free(octet); if (ret <0) return 0; return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); }
/******************************************************************************* 函数名称: cert_ku_accept 功能描述: 查看某个证书是否有某种密钥用途 输入参数: X509 *x:证书 u32 kusage:密钥用途 输出参数: 无 返 回 值: 1,有该密钥用途;-1,没有 -------------------------------------------------------------------------------- 最近一次修改记录: 修改作者:王朝 修改目的:添加新函数 修改日期:2009年12月28日 *********************************************************************************/ s32 cert_ku_accept(X509 *x,u32 kusage) { ASN1_BIT_STRING *usage = NULL; if(NULL != (usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { if(usage->length > 0) { x->ex_kusage = usage->data[0]; if(usage->length > 1) { x->ex_kusage |= usage->data[1] << 8; } } else { x->ex_kusage = 0; } ASN1_BIT_STRING_free(usage); if( (x)->ex_kusage & (kusage) ) { return 1; } else { return -1; } } else { return -1; } }
int main(int argc, char const *argv[]) { long value; int ret, len, i; unsigned char *bitstr = "8"; unsigned char buf2[16]; unsigned char *buf = NULL, *p; ASN1_BIT_STRING *a, *q; a = ASN1_BIT_STRING_new(); printf("len = %d\n", a->length); ASN1_BIT_STRING_set(a, bitstr, strlen(bitstr)); len = i2d_ASN1_BIT_STRING(a, NULL); p = buf =malloc(sizeof(unsigned char) * len); len = i2d_ASN1_BIT_STRING(a, &buf); printf("after i2d der content len = %d\n", len); printf("len = %d\n", len); for (i = 0; i < len; ++i) { /* code */ printf("%02x\n", p[i]); } printf("\n"); q = d2i_ASN1_BIT_STRING(&a, &p, len); printf("after d2i length = %d\n", q->length); for (i = 0; i < q->length; ++i) { printf("%02x\t", q->data[i]); } printf("\n"); ASN1_BIT_STRING_free(a); return 0; }
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **pp, long len) { ASN1_BIT_STRING *ret = NULL; const unsigned char *p; unsigned char *s; int i; if (len < 1) { i = ASN1_R_STRING_TOO_SHORT; goto err; } if ((a == NULL) || ((*a) == NULL)) { if ((ret = ASN1_BIT_STRING_new()) == NULL) return (NULL); } else ret = (*a); p = *pp; i = *(p++); if (i > 7) { i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT; goto err; } /* * We do this to preserve the settings. If we modify the settings, via * the _set_bit function, we will recalculate on output */ ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */ if (len-- > 1) { /* using one because of the bits left byte */ s = OPENSSL_malloc((int)len); if (s == NULL) { i = ERR_R_MALLOC_FAILURE; goto err; } memcpy(s, p, (int)len); s[len - 1] &= (0xff << i); p += len; } else s = NULL; ret->length = (int)len; OPENSSL_free(ret->data); ret->data = s; ret->type = V_ASN1_BIT_STRING; if (a != NULL) (*a) = ret; *pp = p; return (ret); err: ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i); if ((a == NULL) || (*a != ret)) ASN1_BIT_STRING_free(ret); return (NULL); }
static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; unsigned char *buf=NULL,*databuf,*sptr; int i,j,data_len,ret=0; const EC_POINT *pub_key; BIGNUM *X,*Y,*order; const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); if (pk->save_parameters) { ASN1_STRING *params = encode_gost_algor_params(pk); pval = params; ptype = V_ASN1_SEQUENCE; } order = BN_new(); EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL); pub_key=EC_KEY_get0_public_key(ec); if (!pub_key) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); return 0; } X=BN_new(); Y=BN_new(); EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), pub_key,X,Y,NULL); data_len = 2*BN_num_bytes(order); BN_free(order); databuf = OPENSSL_malloc(data_len); memset(databuf,0,data_len); store_bignum(X,databuf+data_len/2,data_len/2); store_bignum(Y,databuf,data_len/2); BN_free(X); BN_free(Y); octet = ASN1_OCTET_STRING_new(); ASN1_STRING_set(octet,NULL,data_len); sptr=ASN1_STRING_data(octet); for (i=0,j=data_len-1;i<data_len;i++,j--) { sptr[i]=databuf[j]; } OPENSSL_free(databuf); ret = i2d_ASN1_OCTET_STRING(octet,&buf); ASN1_BIT_STRING_free(octet); if (ret <0) return 0; return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); }
/** * Returns current certificate key usage bits * * @return key usage bits */ std::vector<digidoc::X509Cert::KeyUsage> digidoc::X509Cert::getKeyUsage() const throw(IOException) { ASN1_BIT_STRING *keyusage = (ASN1_BIT_STRING*)X509_get_ext_d2i(cert, NID_key_usage, 0, 0); if(!keyusage) return std::vector<KeyUsage>(); std::vector<KeyUsage> usage; for(int n = 0; n < 9; ++n) { if(ASN1_BIT_STRING_get_bit(keyusage, n)) usage.push_back(KeyUsage(n)); } ASN1_BIT_STRING_free(keyusage); return usage; }
static VALUE decode_bstr(unsigned char* der, int length, long *unused_bits) { ASN1_BIT_STRING *bstr; const unsigned char *p; long len; VALUE ret; p = der; if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) ossl_raise(eASN1Error, NULL); len = bstr->length; *unused_bits = 0; if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT) *unused_bits = bstr->flags & 0x07; ret = rb_str_new((const char *)bstr->data, len); ASN1_BIT_STRING_free(bstr); return ret; }
/** * @param cert X509 certificate * @return returns if certificate is valid for signing */ bool digidoc::PKCS11SignerPrivate::checkCert( X509 *cert ) const { if(!cert) return false; ASN1_BIT_STRING *keyusage = (ASN1_BIT_STRING*)X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL); if(!keyusage) return false; bool ret = false; for(int n = 0; n < 9; ++n) { if(ASN1_BIT_STRING_get_bit(keyusage, n) && n == 1) { ret = true; break; } } ASN1_BIT_STRING_free( keyusage ); return ret; }
static OCSP_BASICRESP *make_dummy_resp(void) { const unsigned char namestr[] = "openssl.example.com"; unsigned char keybytes[128] = {7}; OCSP_BASICRESP *bs = OCSP_BASICRESP_new(); OCSP_BASICRESP *bs_out = NULL; OCSP_CERTID *cid = NULL; ASN1_TIME *thisupd = ASN1_TIME_set(NULL, time(NULL)); ASN1_TIME *nextupd = ASN1_TIME_set(NULL, time(NULL) + 200); X509_NAME *name = X509_NAME_new(); ASN1_BIT_STRING *key = ASN1_BIT_STRING_new(); ASN1_INTEGER *serial = ASN1_INTEGER_new(); if (!X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC, namestr, -1, -1, 1) || !ASN1_BIT_STRING_set(key, keybytes, sizeof(keybytes)) || !ASN1_INTEGER_set_uint64(serial, (uint64_t)1)) goto err; cid = OCSP_cert_id_new(EVP_sha256(), name, key, serial); if (!TEST_ptr(bs) || !TEST_ptr(thisupd) || !TEST_ptr(nextupd) || !TEST_ptr(cid) || !TEST_true(OCSP_basic_add1_status(bs, cid, V_OCSP_CERTSTATUS_UNKNOWN, 0, NULL, thisupd, nextupd))) goto err; bs_out = bs; bs = NULL; err: ASN1_TIME_free(thisupd); ASN1_TIME_free(nextupd); ASN1_BIT_STRING_free(key); ASN1_INTEGER_free(serial); OCSP_CERTID_free(cid); OCSP_BASICRESP_free(bs); X509_NAME_free(name); return bs_out; }
DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) { int_dhx942_dh *dhx = NULL; DH *dh = NULL; dh = DH_new(); if (dh == NULL) return NULL; dhx = d2i_int_dhx(NULL, pp, length); if (dhx == NULL) { DH_free(dh); return NULL; } if (a) { DH_free(*a); *a = dh; } dh->p = dhx->p; dh->q = dhx->q; dh->g = dhx->g; dh->j = dhx->j; if (dhx->vparams) { dh->seed = dhx->vparams->seed->data; dh->seedlen = dhx->vparams->seed->length; dh->counter = dhx->vparams->counter; dhx->vparams->seed->data = NULL; ASN1_BIT_STRING_free(dhx->vparams->seed); OPENSSL_free(dhx->vparams); dhx->vparams = NULL; } OPENSSL_free(dhx); return dh; }
void X509_KEY_free(X509 *a) { int i; if (a == NULL) return; i=CRYPTO_add_lock(&a->references,-1,CRYPTO_LOCK_X509_KEY); #ifdef REF_PRINT REF_PRINT("X509_KEY",a); #endif if (i > 0) return; #ifdef REF_CHECK if (i < 0) { fprintf(stderr,"X509_KEY_free, bad reference count\n"); abort(); } #endif X509_CINF_free(a->cert_info); X509_ALGOR_free(a->sig_alg); ASN1_BIT_STRING_free(a->signature); OPENSSL_free(a); }
void CryptoNative_Asn1BitStringFree(ASN1_STRING* a) { ASN1_BIT_STRING_free(a); }
static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; ASN1_STRING *params = NULL; void *pval = NULL; unsigned char *buf = NULL, *sptr; int key_size, ret = 0; const EC_POINT *pub_key; BIGNUM *X = NULL, *Y = NULL; const GOST_KEY *ec = pk->pkey.gost; int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); if (pk->save_parameters) { params = encode_gost01_algor_params(pk); if (params == NULL) return 0; pval = params; ptype = V_ASN1_SEQUENCE; } key_size = GOST_KEY_get_size(ec); pub_key = GOST_KEY_get0_public_key(ec); if (pub_key == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); goto err; } octet = ASN1_OCTET_STRING_new(); if (octet == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); goto err; } ret = ASN1_STRING_set(octet, NULL, 2 * key_size); if (ret == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); goto err; } sptr = ASN1_STRING_data(octet); X = BN_new(); Y = BN_new(); if (X == NULL || Y == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); goto err; } if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), pub_key, X, Y, NULL) == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB); goto err; } GOST_bn2le(X, sptr, key_size); GOST_bn2le(Y, sptr + key_size, key_size); BN_free(Y); BN_free(X); ret = i2d_ASN1_OCTET_STRING(octet, &buf); ASN1_BIT_STRING_free(octet); if (ret < 0) return 0; return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); err: BN_free(Y); BN_free(X); ASN1_BIT_STRING_free(octet); ASN1_STRING_free(params); return 0; }
extern "C" void Asn1BitStringFree(ASN1_STRING* a) { ASN1_BIT_STRING_free(a); }
static void x509v3_cache_extensions(X509 *x) { BASIC_CONSTRAINTS *bs; PROXY_CERT_INFO_EXTENSION *pci; ASN1_BIT_STRING *usage; ASN1_BIT_STRING *ns; EXTENDED_KEY_USAGE *extusage; X509_EXTENSION *ex; int i; if(x->ex_flags & EXFLAG_SET) return; #ifndef OPENSSL_NO_SHA X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); #endif /* Does subject name match issuer ? */ if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) x->ex_flags |= EXFLAG_SS; /* V1 should mean no extensions ... */ if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1; /* Handle basic constraints */ if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { if(bs->ca) x->ex_flags |= EXFLAG_CA; if(bs->pathlen) { if((bs->pathlen->type == V_ASN1_NEG_INTEGER) || !bs->ca) { x->ex_flags |= EXFLAG_INVALID; x->ex_pathlen = 0; } else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); } else x->ex_pathlen = -1; BASIC_CONSTRAINTS_free(bs); x->ex_flags |= EXFLAG_BCONS; } /* Handle proxy certificates */ if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { if (x->ex_flags & EXFLAG_CA || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0 || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) { x->ex_flags |= EXFLAG_INVALID; } if (pci->pcPathLengthConstraint) { x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); } else x->ex_pcpathlen = -1; PROXY_CERT_INFO_EXTENSION_free(pci); x->ex_flags |= EXFLAG_PROXY; } /* Handle key usage */ if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { if(usage->length > 0) { x->ex_kusage = usage->data[0]; if(usage->length > 1) x->ex_kusage |= usage->data[1] << 8; } else x->ex_kusage = 0; x->ex_flags |= EXFLAG_KUSAGE; ASN1_BIT_STRING_free(usage); } x->ex_xkusage = 0; if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { x->ex_flags |= EXFLAG_XKUSAGE; for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) { case NID_server_auth: x->ex_xkusage |= XKU_SSL_SERVER; break; case NID_client_auth: x->ex_xkusage |= XKU_SSL_CLIENT; break; case NID_email_protect: x->ex_xkusage |= XKU_SMIME; break; case NID_code_sign: x->ex_xkusage |= XKU_CODE_SIGN; break; case NID_ms_sgc: case NID_ns_sgc: x->ex_xkusage |= XKU_SGC; break; case NID_OCSP_sign: x->ex_xkusage |= XKU_OCSP_SIGN; break; case NID_time_stamp: x->ex_xkusage |= XKU_TIMESTAMP; break; case NID_dvcs: x->ex_xkusage |= XKU_DVCS; break; } } sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); } if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { if(ns->length > 0) x->ex_nscert = ns->data[0]; else x->ex_nscert = 0; x->ex_flags |= EXFLAG_NSCERT; ASN1_BIT_STRING_free(ns); } x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); for (i = 0; i < X509_get_ext_count(x); i++) { ex = X509_get_ext(x, i); if (!X509_EXTENSION_get_critical(ex)) continue; if (!X509_supported_extension(ex)) { x->ex_flags |= EXFLAG_CRITICAL; break; } } x->ex_flags |= EXFLAG_SET; }
int EstEID_loadCertInfoEntries(EstEID_Certs *certs, int index) { EstEID_Map cert = certs->certs[index]; CK_SLOT_ID slotID = certs->slotIDs[index]; CK_SESSION_HANDLE session; FAIL_IF(EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))); CK_OBJECT_CLASS objectClass = CKO_CERTIFICATE; CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)}; if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) return FAILURE; CK_OBJECT_HANDLE objectHandle; CK_ULONG objectCount; if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &objectHandle, 1, &objectCount))) return FAILURE; if (objectCount == 0) return SUCCESS; CK_ATTRIBUTE attribute = {CKA_VALUE, NULL_PTR, 0}; if (EstEID_CK_failure("C_GetAttributeValue", fl->C_GetAttributeValue(session, objectHandle, &attribute, 1))) return FAILURE; CK_ULONG certificateLength = attribute.ulValueLen; CK_BYTE_PTR certificate = (CK_BYTE_PTR)malloc(certificateLength); attribute.pValue = certificate; if (EstEID_CK_failure("C_GetAttributeValue", fl->C_GetAttributeValue(session, objectHandle, &attribute, 1))) return FAILURE; EstEID_mapPutNoAlloc(cert, strdup("certificateAsHex"), EstEID_bin2hex((char *)certificate, certificateLength)); const unsigned char *p = certificate; X509 *x509 = d2i_X509(NULL, &p, certificateLength); char *certMD5; certMD5 = EstEID_getCertHash((char*)certificate); FAIL_IF(EstEID_md5_failure(certMD5)); EstEID_mapPutNoAlloc(cert, strdup("certHash"), certMD5); free(certificate); // todo: error handling of all openssl functions EstEID_mapPutNoAlloc(cert, strdup("validTo"), EstEID_ASN1_TIME_toString(X509_get_notAfter(x509))); EstEID_mapPutNoAlloc(cert, strdup("validFrom"), EstEID_ASN1_TIME_toString(X509_get_notBefore(x509))); unsigned long keyUsage; ASN1_BIT_STRING *usage = (ASN1_BIT_STRING *)X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL); if (usage->length > 0) keyUsage = usage->data[0]; ASN1_BIT_STRING_free(usage); if (keyUsage & X509v3_KU_DIGITAL_SIGNATURE) EstEID_mapPut(cert, "usageDigitalSignature", "TRUE"); if (keyUsage & X509v3_KU_NON_REPUDIATION) { EstEID_mapPut(cert, "usageNonRepudiation", "TRUE"); EstEID_mapPut(cert, "keyUsage", "Non-Repudiation"); // for compatibility with older plugin } EstEID_loadCertEntries(cert, "", X509_get_subject_name(x509)); char *certSerialNumber = (char*)malloc(33); snprintf(certSerialNumber, 32, "%lX", ASN1_INTEGER_get(X509_get_serialNumber(x509))); EstEID_mapPutNoAlloc(cert, strdup("certSerialNumber"), certSerialNumber); EstEID_loadCertEntries(cert, "issuer.", X509_get_issuer_name(x509)); BIO *bio = BIO_new(BIO_s_mem()); if (!PEM_write_bio_X509(bio, x509)) printf("Cannot create PEM\n"); char *b; int len = BIO_get_mem_data(bio, &b); char *pem = (char *)malloc(len + 1); strncpy(pem, b, len); pem[len] = 0; BIO_free(bio); EstEID_mapPutNoAlloc(cert, strdup("certificateAsPEM"), pem); FAIL_IF(EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))); return SUCCESS; }