Route EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL through a CBS.

This is the only EVP_PKEY ctrl hook which returns something other than a
boolean.

Change-Id: Ic226aef168abdf72e5d30e8264a559ed5039a055
Reviewed-on: https://boringssl-review.googlesource.com/3873
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/err/evp.errordata b/crypto/err/evp.errordata
index 8cb7b1e..e0346b4 100644
--- a/crypto/err/evp.errordata
+++ b/crypto/err/evp.errordata
@@ -2,6 +2,7 @@
 EVP,function,101,EVP_DigestVerifyInitFromAlgorithm
 EVP,function,102,EVP_PKEY_CTX_ctrl
 EVP,function,103,EVP_PKEY_CTX_dup
+EVP,function,159,EVP_PKEY_CTX_get0_rsa_oaep_label
 EVP,function,104,EVP_PKEY_copy_parameters
 EVP,function,105,EVP_PKEY_decrypt
 EVP,function,106,EVP_PKEY_decrypt_init
diff --git a/crypto/evp/p_rsa.c b/crypto/evp/p_rsa.c
index 615f6f8..be2229b 100644
--- a/crypto/evp/p_rsa.c
+++ b/crypto/evp/p_rsa.c
@@ -55,10 +55,12 @@
 
 #include <openssl/evp.h>
 
+#include <limits.h>
 #include <string.h>
 
 #include <openssl/bn.h>
 #include <openssl/buf.h>
+#include <openssl/bytestring.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
@@ -480,8 +482,8 @@
         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
         return -2;
       }
-      *(uint8_t **)p2 = rctx->oaep_label;
-      return rctx->oaep_labellen;
+      CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen);
+      return 1;
 
     case EVP_PKEY_CTRL_DIGESTINIT:
       return 1;
@@ -595,6 +597,15 @@
 
 int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
                                      const uint8_t **out_label) {
-  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
-                           EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *) out_label);
+  CBS label;
+  if (EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+                        EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label) != 1) {
+    return -1;
+  }
+  if (CBS_len(&label) > INT_MAX) {
+    OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_get0_rsa_oaep_label, ERR_R_OVERFLOW);
+    return -1;
+  }
+  *out_label = CBS_data(&label);
+  return (int)CBS_len(&label);
 }
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 26e4f2f..1e17a46 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -824,6 +824,7 @@
 #define EVP_F_rsa_pss_to_ctx 156
 #define EVP_F_rsa_pub_decode 157
 #define EVP_F_pkey_hmac_ctrl 158
+#define EVP_F_EVP_PKEY_CTX_get0_rsa_oaep_label 159
 #define EVP_R_BUFFER_TOO_SMALL 100
 #define EVP_R_COMMAND_NOT_SUPPORTED 101
 #define EVP_R_CONTEXT_NOT_INITIALISED 102