New functions to get key types without dereferncing EVP_PKEY.

More error checking for RSA pmeth.
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index ae7bee8..73f211e 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -717,6 +717,8 @@
 			const unsigned char *key,int key_len,
 			EVP_PKEY *pub_key);
 int		EVP_PKEY_type(int type);
+int		EVP_PKEY_id(const EVP_PKEY *pkey);
+int		EVP_PKEY_base_id(const EVP_PKEY *pkey);
 int		EVP_PKEY_bits(EVP_PKEY *pkey);
 int		EVP_PKEY_size(EVP_PKEY *pkey);
 int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 730520f..752547d 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -297,6 +297,16 @@
 	return NID_undef;
 	}
 
+int EVP_PKEY_id(const EVP_PKEY *pkey)
+	{
+	return pkey->type;
+	}
+
+int EVP_PKEY_base_id(const EVP_PKEY *pkey)
+	{
+	return EVP_PKEY_type(pkey->type);
+	}
+
 void EVP_PKEY_free(EVP_PKEY *x)
 	{
 	int i;
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index 74fcdee..d24e4d7 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -372,6 +372,8 @@
 /* Function codes. */
 #define RSA_F_CHECK_PADDING_MD				 140
 #define RSA_F_MEMORY_LOCK				 100
+#define RSA_F_PKEY_RSA_CTRL				 143
+#define RSA_F_PKEY_RSA_CTRL_STR				 144
 #define RSA_F_PKEY_RSA_SIGN				 142
 #define RSA_F_PKEY_RSA_VERIFYRECOVER			 141
 #define RSA_F_RSA_BUILTIN_KEYGEN			 129
@@ -433,12 +435,15 @@
 #define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
 #define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
 #define RSA_R_FIRST_OCTET_INVALID			 133
+#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE	 144
 #define RSA_R_INVALID_DIGEST				 105
 #define RSA_R_INVALID_DIGEST_LENGTH			 143
 #define RSA_R_INVALID_HEADER				 137
+#define RSA_R_INVALID_KEYBITS				 145
 #define RSA_R_INVALID_MESSAGE_LENGTH			 131
 #define RSA_R_INVALID_PADDING				 138
 #define RSA_R_INVALID_PADDING_MODE			 141
+#define RSA_R_INVALID_PSS_SALTLEN			 146
 #define RSA_R_INVALID_TRAILER				 139
 #define RSA_R_INVALID_X931_DIGEST			 142
 #define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
@@ -458,6 +463,7 @@
 #define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
 #define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
 #define RSA_R_UNKNOWN_PADDING_TYPE			 118
+#define RSA_R_VALUE_MISSING				 147
 #define RSA_R_WRONG_SIGNATURE_LENGTH			 119
 
 #ifdef  __cplusplus
diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c
index cfbbfa8..7dcf766 100644
--- a/crypto/rsa/rsa_err.c
+++ b/crypto/rsa/rsa_err.c
@@ -72,6 +72,8 @@
 	{
 {ERR_FUNC(RSA_F_CHECK_PADDING_MD),	"CHECK_PADDING_MD"},
 {ERR_FUNC(RSA_F_MEMORY_LOCK),	"MEMORY_LOCK"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL),	"PKEY_RSA_CTRL"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR),	"PKEY_RSA_CTRL_STR"},
 {ERR_FUNC(RSA_F_PKEY_RSA_SIGN),	"PKEY_RSA_SIGN"},
 {ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER),	"PKEY_RSA_VERIFYRECOVER"},
 {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
@@ -136,12 +138,15 @@
 {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
 {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
 {ERR_REASON(RSA_R_FIRST_OCTET_INVALID)   ,"first octet invalid"},
+{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"},
 {ERR_REASON(RSA_R_INVALID_DIGEST)        ,"invalid digest"},
 {ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"},
 {ERR_REASON(RSA_R_INVALID_HEADER)        ,"invalid header"},
+{ERR_REASON(RSA_R_INVALID_KEYBITS)       ,"invalid keybits"},
 {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
 {ERR_REASON(RSA_R_INVALID_PADDING)       ,"invalid padding"},
 {ERR_REASON(RSA_R_INVALID_PADDING_MODE)  ,"invalid padding mode"},
+{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN)   ,"invalid pss saltlen"},
 {ERR_REASON(RSA_R_INVALID_TRAILER)       ,"invalid trailer"},
 {ERR_REASON(RSA_R_INVALID_X931_DIGEST)   ,"invalid x931 digest"},
 {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
@@ -161,6 +166,7 @@
 {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
 {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
 {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE)  ,"unknown padding type"},
+{ERR_REASON(RSA_R_VALUE_MISSING)         ,"value missing"},
 {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
 {0,NULL}
 	};
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
index 01a4030..3788406 100644
--- a/crypto/rsa/rsa_pmeth.c
+++ b/crypto/rsa/rsa_pmeth.c
@@ -362,34 +362,44 @@
 				return 0;
 			if (p1 == RSA_PKCS1_PSS_PADDING) 
 				{
-				if (ctx->operation == EVP_PKEY_OP_VERIFYRECOVER)
-					return -2;
+				if (!(ctx->operation &
+				     (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
+					goto bad_pad;
 				if (!rctx->md)
 					rctx->md = EVP_sha1();
 				}
 			if (p1 == RSA_PKCS1_OAEP_PADDING) 
 				{
 				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
-					return -2;
+					goto bad_pad;
 				if (!rctx->md)
 					rctx->md = EVP_sha1();
 				}
 			rctx->pad_mode = p1;
 			return 1;
 			}
+		bad_pad:
+		RSAerr(RSA_F_PKEY_RSA_CTRL,
+				RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
 		return -2;
 
 		case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
 		if (p1 < -2)
 			return -2;
 		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
 			return -2;
+			}
 		rctx->saltlen = p1;
 		return 1;
 
 		case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
 		if (p1 < 256)
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
 			return -2;
+			}
 		rctx->nbits = p1;
 		return 1;
 
@@ -418,11 +428,14 @@
 static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
 			const char *type, const char *value)
 	{
+	if (!value)
+		{
+		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
+		return 0;
+		}
 	if (!strcmp(type, "rsa_padding_mode"))
 		{
 		int pm;
-		if (!value)
-			return 0;
 		if (!strcmp(value, "pkcs1"))
 			pm = RSA_PKCS1_PADDING;
 		else if (!strcmp(value, "sslv23"))
@@ -436,7 +449,11 @@
 		else if (!strcmp(value, "pss"))
 			pm = RSA_PKCS1_PSS_PADDING;
 		else
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
+						RSA_R_UNKNOWN_PADDING_TYPE);
 			return -2;
+			}
 		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
 		}