RSA_MIN_MODULUS_BITS, 0, 2);
RSA_MIN_MODULUS_BITS, 0, 0);
pk11_handlePublicKeyObject(PK11Session *session, PK11Object *object,							 CK_KEY_TYPE key_type){    CK_BBOOL encrypt = CK_TRUE;    CK_BBOOL recover = CK_TRUE;    CK_BBOOL wrap = CK_TRUE;    CK_BBOOL derive = CK_FALSE;    CK_BBOOL verify = CK_TRUE;    CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;    PK11Attribute *attribute;    CK_RV crv;    switch (key_type) {    case CKK_RSA:	crv = pk11_ConstrainAttribute(object, CKA_MODULUS,						 RSA_MIN_MODULUS_BITS, 0, 2);	if (crv != CKR_OK) {	    return crv;	}	crv = pk11_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT, 2, 0, 0);	if (crv != CKR_OK) {	    return crv;	}	pubKeyAttr = CKA_MODULUS;	break;    case CKK_DSA:	crv = pk11_ConstrainAttribute(object, CKA_SUBPRIME, 						DSA_Q_BITS, DSA_Q_BITS, 0);	if (crv != CKR_OK) {	    return crv;	}	crv = pk11_ConstrainAttribute(object, CKA_PRIME, 					DSA_MIN_P_BITS, DSA_MAX_P_BITS, 64);	if (crv != CKR_OK) {	    return crv;	}	crv = pk11_ConstrainAttribute(object, CKA_BASE, 1, DSA_MAX_P_BITS, 0);	if (crv != CKR_OK) {	    return crv;	}	crv = pk11_ConstrainAttribute(object, CKA_VALUE, 1, DSA_MAX_P_BITS, 0);	if (crv != CKR_OK) {	    return crv;	}	encrypt = CK_FALSE;	recover = CK_FALSE;	wrap = CK_FALSE;	break;    case CKK_DH:	crv = pk11_ConstrainAttribute(object, CKA_PRIME, 					DH_MIN_P_BITS, DH_MAX_P_BITS, 0);	if (crv != CKR_OK) {	    return crv;	}	crv = pk11_ConstrainAttribute(object, CKA_BASE, 1, DH_MAX_P_BITS, 0);	if (crv != CKR_OK) {	    return crv;	}	crv = pk11_ConstrainAttribute(object, CKA_VALUE, 1, DH_MAX_P_BITS, 0);	if (crv != CKR_OK) {	    return crv;	}	verify = CK_FALSE;	derive = CK_TRUE;	encrypt = CK_FALSE;	recover = CK_FALSE;	wrap = CK_FALSE;	break;#ifdef NSS_ENABLE_ECC    case CKK_EC:	if ( !pk11_hasAttribute(object, CKA_EC_PARAMS)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_EC_POINT)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	pubKeyAttr = CKA_EC_POINT;	derive = CK_TRUE;    /* for ECDH */	verify = CK_TRUE;    /* for ECDSA */	encrypt = CK_FALSE;	recover = CK_FALSE;	wrap = CK_FALSE;	break;#endif /* NSS_ENABLE_ECC */    default:	return CKR_ATTRIBUTE_VALUE_INVALID;    }    /* make sure the required fields exist */    crv = pk11_defaultAttribute(object,CKA_SUBJECT,NULL,0);    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_VERIFY,&verify,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_VERIFY_RECOVER,						&recover,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     object->objectInfo = pk11_GetPubKey(object,key_type, &crv);    if (object->objectInfo == NULL) {	return crv;    }    object->infoFree = (PK11Free) nsslowkey_DestroyPublicKey;    if (pk11_isTrue(object,CKA_TOKEN)) {	PK11Slot *slot = session->slot;	NSSLOWKEYPrivateKey *priv;	SECItem pubKey;	crv = pk11_Attribute2SSecItem(NULL,&pubKey,object,pubKeyAttr);	if (crv != CKR_OK) return crv;	PORT_Assert(pubKey.data);	if (slot->keyDB == NULL) {	    PORT_Free(pubKey.data);	    return CKR_TOKEN_WRITE_PROTECTED;	}	if (slot->keyDB->version != 3) {	    unsigned char buf[SHA1_LENGTH];	    SHA1_HashBuf(buf,pubKey.data,pubKey.len);	    PORT_Memcpy(pubKey.data,buf,sizeof(buf));	    pubKey.len = sizeof(buf);	}	/* make sure the associated private key already exists */	/* only works if we are logged in */	priv = nsslowkey_FindKeyByPublicKey(slot->keyDB, &pubKey,							 slot->password);	if (priv == NULL) {	    PORT_Free(pubKey.data);	    return CKR_ATTRIBUTE_VALUE_INVALID;	}	nsslowkey_DestroyPrivateKey(priv);	object->handle = pk11_mkHandle(slot, &pubKey, PK11_TOKEN_TYPE_PUB);	PORT_Free(pubKey.data);    }    return CKR_OK;}