bool certGetProperty(CertInstance *obj, NPIdentifier name, NPVariant *variant) {
	NPUTF8* nameString = browserFunctions->utf8fromidentifier(name);
	EstEID_log("name=%s", (char *)nameString);
	if(isSameIdentifier(name, "id")){
		return copyStringToNPVariant(EstEID_getCertHash(obj->certificate), variant);
	}
	if(isSameIdentifier(name, "certificateAsHex") || isSameIdentifier(name, "cert")){
		return copyStringToNPVariant(obj->certificateAsHex, variant);
	}
	if(isSameIdentifier(name, "issuerCN")){
		return copyStringToNPVariant(obj->issuerCN, variant);
	}
	if(isSameIdentifier(name, "CN")){
		EstEID_log("CN=%s", obj->CN);
		return copyStringToNPVariant(obj->CN, variant);
	}
	if(isSameIdentifier(name, "validTo")){
		return copyStringToNPVariant(obj->validTo, variant);
	}
	if(isSameIdentifier(name, "validFrom")){
		return copyStringToNPVariant(obj->validFrom, variant);
	}
	if(isSameIdentifier(name, "keyUsage")){
		return copyStringToNPVariant("Non-Repudiation", variant);
	}
	return false;
}
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;
}