OpenSSL signing and CAPI verification - c++

I'm working with CAPICOM libary, but it is not available on Android and iOS. As far as i know, CAPICOM signed message is in PKCS#7 format, then i want to use OpenSSL to create signed message like CAPICOM did.
The OpenSSL commands i used:
iconv -f utf-8 -t utf-16le data.bin > data-utf16le.bin
openssl smime -sign -binary -noattr -in data-utf16le.bin -signer demo.pem -inkey demo.key -out sign.txt -outform PEM
then i verified with CAPICOM as this sample: http://www.codeproject.com/Articles/9691/Using-CAPICOM-in-NET-for-Digital-Signatures-with-A
The verify method is:
public bool VerifyDetachedSignature(string plaintextMessage, string signedContent, Encoding encodingType)
{
try
{
this._clearText = plaintextMessage;
this._signedContent = signedContent;
CAPICOM.SignedData signedData = new CAPICOM.SignedDataClass();
CAPICOM.Utilities u = new CAPICOM.UtilitiesClass();
IntPtr _content = u.ByteArrayToBinaryString(encodingType.GetBytes(plaintextMessage));
signedData.set_Content(_content);
int len = _signedContent.Length;
signedData.Verify(_signedContent,true, CAPICOM.CAPICOM_SIGNED_DATA_VERIFY_FLAG.CAPICOM_VERIFY_SIGNATURE_ONLY);
SignerCert=null;
CAPICOM.Signer s = (CAPICOM.Signer) signedData.Signers[1];
SignerCert = (CAPICOM.Certificate)s.Certificate;
return true;
}
catch(COMException e)
{
return false;
}
}
encodingType is System.Text.Encoding.UTF8.
The result is invalid.
I sign again with CAPICOM and i saw that the length of signed message in this case is longer than the length of signed message created by OpenSSL.
Please help me to understand!

Related

What do I wrong? Botan & QT & SHELL decrypting

first i create my singing keys:
(Shell/Debian 9)
>openssl genrsa -out ./priv.rsa 2048
>openssl pkcs8 -topk8 -inform PEM -outform PEM -in ./priv.rsa -out priv.pem
>openssl rsa -in ./priv.pem -pubout -out pub.pem
Then i ceate my encrypt.txt with
(Shell)
> echo "ęśłżół">encrypt.txt
and crypt it with my public Rsa key
(Shell)
> openssl rsautl -encrypt -inkey ./pub.pem -pubin -in ./encrypt.txt -out
> ./encrypt.dat
.. and than comes Botan (dowloaded yesterday) with QT (5.9.1):
...
using namespace Botan;
using std::string;
QFile file,file2;
// Reading private key
file.setFileName(".../priv.pem");
file.open(QIODevice::ReadOnly);
QByteArray f = file.readAll();
file.close();
//reading encrypted file
file2.setFileName("...../encrypt.dat");
file2.open(QIODevice::ReadOnly);
QByteArray f2 = file2.readAll();
file2.close();
enter code here
std::vector<uint8_t> ct;
for(QByteArray::Iterator it = f2.begin();it!=f2.end();it++)
{
ct.push_back((uint8_t)(*it));
}
string password=ui->lineEdit_2->text().toStdString().c_str();
std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);
DataSource_Memory keyData2( f.toStdString().c_str() );
std::unique_ptr<Private_Key> kp = PKCS8::load_key(keyData2,pass);
PK_Decryptor_EME dec(*kp,*rng.get(), "Raw");
secure_vector<uint8_t> ct4=dec.decrypt(ct);
QByteArray aaa;
for(secure_vector<uint8_t>::iterator it=ct4.begin();it!=ct4.end();it++)
{
aaa+=(uint8_t)(*it);
}
QFile fileX(".../encryptE.txt");
fileX.open(QIODevice::WriteOnly);
fileX.write(aaa);
fileX.close();
...and my Out file contains (and is 255 byte wide):
^B4�����x��^V�&��ߵݹ�*S�^T�㓠K��7�J CF^U^B^[��^Q��
=^H�+�7Y^^^U�^^O\�v�����bdK^N^Ev^QI=����)�)��n^KПV����Y�-23^^�5]���^\�լ1^U�9n�z萘Å^A��Vr��8�#^C�^S����o��0����S[x�
��2 �^P4�^L�p��i���t^D���
��^Z��J^K�^G^Z^\�4\^D^Z^Ew^Tx�S�ٛ��i�5�^D��A��Ƨ�o�zÚ��#���^L�^G���Ŋ^FXIu��^#ęśłżół
My questions:
1. ... i see my string: ęśłżół .... but what do I wrong ? - decodedfile isn't orginal one?
I'is allowed to my to use RAW type only like (FOR THIS FILE: encrpted.dat):
PK_Decryptor_EME dec(*kp,*rng.get(), "Raw");
if i choose : PKCS1v15” || “EME-PKCS1-v1_5”
“OAEP” || “EME-OAEP” || “EME1” || “EME1(SHA-1)” || “EME1(SHA-256)”
i become error:
terminate called after throwing an instance of 'Botan::Decoding_Error'
what(): Invalid argument Decoding error: Invalid public key ciphertext, cannot decrypt
OpenSSL defaults to the less secure PKCS#1 v1.5 padding. To use the same unpadding you should probably use "PKCS1v15" in Botan.
Beware that PKCS#1 v1.5 is succeptible to the Bleichenbacher (padding oracle) attack, so the use of PKCS#1 v1.5 padding should be used with care (i.e. not in automated systems that can act as a padding oracle).
Using OAEP is recommended.

Boost.Asio SSL context load_verify_paths not loading certificate(s)

I have code to retrieve all root certificates in the Windows certificate store for the current user:
#include <windows.h>
#include <Wincrypt.h>
inline std::vector<std::string> system_root_certificates()
{
std::vector<std::string> certs;
HCERTSTORE hStore;
PCCERT_CONTEXT pCertContext = NULL;
if (!(hStore = ::CertOpenStore(
CERT_STORE_PROV_SYSTEM_A,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
"Root")))
return certs;
do
{
if (pCertContext = ::CertFindCertificateInStore(
hStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_ANY,
NULL,
pCertContext))
{
certs.push_back("-----BEGIN CERTIFICATE-----\n" +
Base64::encode_copy(std::string((char *) pCertContext->pbCertEncoded, (size_t) pCertContext->cbCertEncoded), true) +
"\n-----END CERTIFICATE-----\n");
}
} while (pCertContext);
if (!pCertContext)
::CertFreeCertificateContext(pCertContext);
::CertCloseStore(
hStore,
CERT_CLOSE_STORE_FORCE_FLAG);
return certs;
}
Then I write the certificates out to a file:
...
for (size_t i = 0; i < certs.size(); ++i)
certFile << certs[i];
...
I have verified that the file is being written correctly.
A sample of the first two certificates from the file:
-----BEGIN CERTIFICATE-----
MIIFMIIDoAMCAgIQrRahoKWtc1j0Ey5lDQYJhkiGDQEBBQAwMRMwBgoJJomTLGQBFgNjbTEZFwYK
kiaJ8ixkGRYJaWNyc29mMS0wBgNVAxMkaWNyc29mIFJvdCBDcnRpaWNhZSBBdGhvaXR5HhcNMTA1
OTIzOTIyFw0yMDUwMjMyMTNaXzETEQYKkiaJ8ixkGRYDb20xMBcGCZImk/IsARkWbWljb3NvdDEt
KwYDBAMTTWljb3NvdCBSb3QgZXJ0ZmljdGUgdXRocml0MIICMA0GKoZI9w0BAQUAggIPMIICAoIC
APNdgGfUp6kMkCDQCDx1zbcHnInazsNgkWhalHEpdnzCyCV2Dlj6NDbmr/eA6VgLk+Wd43ci9zRk
IpEd4QmQFP78WBnhtweSrohZ2J8HA1j8KW0y0qjL/OELMk/muK1PXG8TmduVdduot5SRd1v1DI9q
fRRwfW2v9dpwR7e/L2znt+ERrHmRfMXW5OF+w37l0jwANoLe4W3zbvifyctSc5g2i6FrlZeb3sJN
/waWJQbIrOTuM5UxyDUINMp51bW+MllAwKVOTT3bBzPkv+8/ZNhCNVf9RXwkTZ7WdBGXkM5odJJv
S2+w48c2oND8wFr5YbkwcZYKsJHAle8QKGrjH7HkAz93BMcgSQ8diKTXfoitLexFxFEEKvzsnpoR
W97OiObi/ayVKEDbBJDfMznZRaUjBqVVMbsGYA5BfR8ul8sRFdUklO8Vif1L+jJb0TMAWWJwMuou
QC173SFnMJmPqiOo0bBumzbEQHScWGXBHnpbyI+7JnzUQOW2bKqGAL/ONQIDAAGjME8wBgNVDwQE
AgHGDwYDHRMB/wQFAwEBMB0GVR0OFgQUrIJgVieXJRP84QpTWeSkEAYJBgEEgjcVBAMCADANCSqG
hvcNAQUFA4ICAMURAzpgXVIRj7K7yLIFtLeoIJ1cA7Yc+gYTtshjmkdvV9JVBLEm1qlQoLzSbszD
rN8ZeKxZrGY0xBs+OEwzMBINJv5RAP+vToQNH+RtLk6FjWwzVNJkv1Cvejmg7WMD/BMGFjbUO5Ub
YjrlF9QFkponW6q9u77jiWBxVrOl0G0OfpUDaD3yY7hrtugw4cqU96KqmTCyp8JRKCABJytLt50R
cL6ygrwMaNCNJIeqKHKdX1mQ9d6TOmJaOeKIHbkGwYlr12nDEjaEyaDaL2l45Xra1wzAvWMXORM4
Nlt7hVZqZGLB4qq/ZqKUEpxmEGvyMJItKfA9FENo8Zwpy844JW18834kJAMIR+yll/UYz7vVdpbv
zttWlaBCl1jhMSLTWeY+IgDqhLYl2fMIaMBkHXzsk6Jibi7YWI/ESSbdKTWHMHFwFDxpiRJ9LqP+
f56CUgorQyvZiJ/I+4mNoYV1fmyecxNkaaUvypZt+ARNkj1uFCHJ4MP9a51K0aGdQ3c/2g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICMIICoAMCAgIBMA0GKoZI9w0BBAUAgYsxMAkGVQQGAlpBFTATA1UEEwxXc3RlbiBDcGUxMBIG
VQQHC0R1YmFuaWxsMQ8wBgNVChMGaGF3ZTEdGwYDBAsTVGhhdGUgZXJ0ZmljdGlvMR8wBgNVAxMW
aGF3ZSBUbWVzYW1wbmcgQTAeDTk3MTAxMDAwMFoXMjAxMzEyNTk1WjCBMQswBgNVBhMCQTEVEwYD
BAgTV2VzZXJuQ2FwMRQwBgNVBxMLdXJibnZpbGUxMA0GVQQKBlRod3RlHTAbA1UEExRUYXd0IENl
dGlmY2F0b24xMB0GVQQDFlRod3RlVGltc3RhcGluIENBgZ8wBgkqSIb3AQEBAAOBADCBAoGB1itY
YUWG6jR7nO2wLhgO4F+o07TJfFlODnNUwX/2Luk6JBU8RwRjnsSUWt9M89lDPBB6JduQ8FHn1kEA
nyjfvpS7thTjhdep4EyksCsa8vg7PkWskgC0QZj77fq3iviIAgMBAaMTETAPA1UdAQH/BTADAf8w
BgkqSIb3AQEEAAOBAGfbwuaHQIOGNX0fmsMMIKi6BImG9RAIv8uiitBNPvTXacZesJRvuefeiLZ7
4yflw/A1y7UnM3ncpgCe+vzNlEIW0xxov1zdqXsQMnRUMYuFhJG3ATAUryjKsVAZCayJ0w==
-----END CERTIFICATE-----
I then close the file, and call
sslContext->load_verify_file(filename);
The load_verify_file function fails with error too long. The function also fails if I only write one certificate to the file, with the same error code.
openssl verify <cert_filename> returns the following (complete) output:
unable to load certificate
2404:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:.\crypto\asn1\asn1_lib.c:142:
2404:error:0D068066:asn1 encoding routines:ASN1_CHECK_TLEN:bad object header:.\crypto\asn1\tasn_dec.c:1303:
2404:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:380:Type=X509
2404:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:.\crypto\pem\pem_oth.c:83:
Is the error caused by the format that I am writing to the file in? What else could cause this error?
Use base64 -d to decode the certificate, it shows der formatted binary, but the length is not correct, e.g. the first certificate's der format indicates 0x0530 + 4 bytes. The der file shall have 1332 bytes, but actually it's only 1078 bytes.
So it indicates that the certificate is corrupted.
Google this topic, it's found that CryptBinaryToString() is a better option to convert the pbCertEncoded, instead of directly calling Base64 function to get the string.

OpenSSL C++ RSA sign is different from command line sign

I'm trying to sign a text in C++ and then verify it in the command line. I'm using OpenSSL libraries. This is my command line for key generation:
openssl genrsa -out key.pem 1024
Now I have my private key. Then this is how I do to sign in command line:
echo "hola" | openssl rsautl -pkcs -sign -inkey key.pem > sign.txt
At this point all works like it seems to be, now I have a sign in sign.txt.
Now I'm trying to do the same in C... This is my code:
RSA * rsaPrivKey;
RSA * createRSAWithFilename (const char * filename, int publicKey)
{
FILE * fp = fopen (filename, "rb");
if (fp == NULL)
{
printf ("Unable to open file %s \n", filename);
return NULL;
}
RSA *rsa = RSA_new ();
if (publicKey)
rsa = PEM_read_RSA_PUBKEY (fp, &rsa, NULL, NULL);
else
rsa = PEM_read_RSAPrivateKey (fp, &rsa, NULL, NULL);
return rsa;
}
void initRSA (void)
{
rsaPrivKey = createRSAWithFilename ("key.pem", 0);
unsigned char text[] = {"hola"};
unsigned char encrypted[4098] = {};
unsigned int outlen;
unsigned char hash[20];
if (!SHA1 (text, sizeof(text), hash)){
printf ("SHA1 failed\n");
exit (0);
}
if (!RSA_sign (NID_sha1, hash, 20, encrypted, &outlen, rsaPrivKey)){
printf ("RSA_sign failed\n");
exit (0);
}
printf ("Result:\n");
for (int a = 0; a < outlen; a++)
printf ("%c", encrypted[a]);
exit (1);
}
When I call initRSA() it prints the generated signature.. but.. is not the same as in generated in command line.
Because not sure about if the sizeof is taking the real length of "text" I tried with length = 4 (hola have 4 chars) and 5 (perhaps computing \0) and the results are not the expected.
My knowledge in cryptography is very limited.. don't know where is the problem.
Apparently it's because you're using the wrong command line. You want this command line, which computes a digest of your input and signs it using the private key:
echo -n "hola" | openssl dgst -sha1 -binary -sign key.pem >sign.txt
Using pkeyutl does some other extra stuff as described here: Different signatures when using C routines and openssl dgst, rsautl commands
So if you use the command line I provided (use echo -n to avoid adding a newline) and change your code to sizeof(text)-1 to skip the null terminator, you should get the same output.

Crash in d2i_RSAPrivateKey_fp()

I have a small VC++ code to load an ASN.1 .der file and read its private key. It compiles and runs fine, but it crashes at function d2i_RSAPrivateKey_fp.
Tools Used:
Visual Studio 2008 [V90]
OpenSSL 1.0.2d 9 Jul 2015
I have also tested the certificate to check if it was corrupted
Testing certificate:
C:\OpenSSL-Win32\bin>openssl rsa -in private.der -check -inform DER
RSA key ok
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC/4V4jxRYeFBDh8XBNq2EMs3hXWW5IIN51lM/Oyz0U/Bw8HF0m
/VBJU3SCy2FzoYPa2o3HHYWDMnjmOlXb9aXR3hyLHnvgvE/0YkMXlxh58H1srjw4
FL7cLXe+lwFbZYtxRaHyn/3U3NIkZkCzR74oxHwyWJ1/zz+TzpmNx8AfyQIDAQAB
AoGAMn+9puxXxdLCHrTMOaTBBfa11UdUHueHpKplhqc2jC9NvwQ3/+rrFmFAaKve
GfCIIzEh3yWF3eGKsAzqS9l6qiyAT+LaCPcn7FbAsaMdVGPc4G290/3maASjQMj6
YfNTcmvPaqfq2+B+aNunS0pi6XGv3917KdGo4hTa2xFXwAECQQDfm5Rh0CjDwhjh
urghbvBgGVRJiAFowgp9xdJj8Hm/U+zXK9Tz2SwVcbEKbcqSVZqB8Keb11TEfF3W
JGIHGdOJAkEA260wKNAdWxgEXiSCEx/tSV3bcRQg4ypTqODc0cWtM295/lhV2Hgx
3zWQ5NiBYZsU104DLWlxnqulJKyBECmaQQJAFAjskpcEEAYkFJWWSeiWwQWD99Kn
zasVJY/D+hBh2DK81cqnmfGrcYBuTHDp5ZKl9V6Kpfv1LGW4Qqef4OL/gQJAb1Mp
IMW22r8lF4Bw2rhHS/LgjkGhGP4OP3sU7Mm8qGBJ9ndVqcnfnDpNH2wIxSoOOb4z
JgRVrA9YNWmmTkaHAQJBANiY3RDyEouYoNKN0oWXsZ/N6BwSFOYAAknmdY5uRwu2
tUQHFiW7u2wZCFmIZVqSBZc5XBdZcmffZeEiO1nVYH4=
-----END RSA PRIVATE KEY-----
C:\OpenSSL-Win32\bin>
Below is the code for the project.
Thing I have tried:
Win32OpenSSL-0_9_8zg (but same issue), OpenSSL 1.0.1
Tried linking libeay to MD, MDd, MT
Set flags to Generate /MAP, /MAPINFO:EXPORTS ,/ASSEMBLYDEBUG
exported to VS2010 project and compiled with openssl32 for VS2010
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <stdio.h>
int main()
{
int ret;
RSA *pkey=NULL;//RSA_new();
RSA *rsa =NULL;//RSA_new();
unsigned char text[2048/8] = "this is a test string";
unsigned char encrypted[4098]={};
unsigned char decrypted[4098]={};
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
ERR_load_ERR_strings();
FILE *fp;
fp = fopen("C:/Users/Public/private.der","rb");
if (fp != NULL)
{
rsa = d2i_RSAPrivateKey_fp(fp, &pkey); // <<< CRASH
}
else
{
//return "Error::Unable to read private key file";
}
if (rsa)
{
// RSA is good
ret = RSA_private_encrypt(RSA_size(pkey), text, encrypted, pkey, RSA_NO_PADDING);
if (ret == -1)
{
fclose(fp);
//return "Error::Failed to encrypt the data";
}
}
else
{
fclose(fp);
//return "Error::Failed to get *RSA Handle1";
}
fclose(fp);
}
Second attempt
I am facing issue with importing private key from ASN.1 .der file to a .pem file.
C:\OpenSSL-Win32\bin>openssl rsa -in private.der -inform DER -out privatepem.pem -outform PEM
writing RSA key
Now, I have .PEM file which have private key in Base64 Form which i will convert it to RSA *rsa; structure.
int main()
{
int ret;
RSA *pkey=NULL;//RSA_new();
RSA *rsa =NULL;//RSA_new();
FILE *fp;
fp = fopen("C:/Users/Public/privatepem.pem","r");
if(PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) == NULL) // <<<CRASH
{
printf("\n%s\n", "Error Reading public key");
}
else
{
printf("\n%s\n", "Private key Imported");
}
return 0;
}
But the new code operating on .pem files has a crash while copying to RSA structure at PEM_read_RSAPrivateKey.
Why am I getting the crash? Is there something I am missing to do, may be initialization of some sort or something wrong with the key?
See the warnings at d2i_X509. This code will attempt to free (or reuse parts of) the pkey object:
if (fp != NULL)
rsa = d2i_RSAPrivateKey_fp(fp, &pkey); /* CRASH */
OpenSSL is not exactly known for validating parameters before taking actions on them :)
Instead, use:
if (fp != NULL)
rsa = d2i_RSAPrivateKey_fp(fp, NULL);
Or:
RSA* pkey = RSA_new();
...
if (fp != NULL)
rsa = d2i_RSAPrivateKey_fp(fp, &pkey);
Also see Seg fault from d2i_RSAPrivateKey_fp on the OpenSSL Users mailing list.
As for the crash after using the API as directed, then it sounds like you have other issues. Since OpenSSL is cross-platofrm, its "write once, run everywhere". Port the OpenSSL-based TLS logic to Linux, and get a memory checker like Valgrind on it.
Problem was solved by replacing the OpenSSL binaries.
Code worked without any changes.
Project had prebuild dependencies of OpenSSL which was from unknown source.
So just by replacing dependencies from "https://slproweb.com/products/Win32OpenSSL.html" it worked like a charm.
:)
Thanks guys

Unable to decrypt the base64 decoded string using private key

I have a base64 string of encrypted string and using BIO_f_base64() I decoded and wrote to a file(decoded.txt) using ofstream(c++ code).
for decrypting I used below command(terminal)
openssl rsautl -decrypt -inkey private.key -in decoded.txt -out plaintext.txt
this will throw an error "RSA_EAY_PRIVATE_DECRYPT data greater than mod".
but when I decode it base64 string through terminal using
echo "base64 string" | base64 --decode >> terminal_decode.txt
and run
openssl rsautl -decrypt -inkey private.key -in terminal_decode.txt -out plaintext.txt
works fine. I compared decode.txt and terminal_decode.txt, both looks same.
Using encoded.txt file I'm unable to decrypt the string, Please help me on solving this
Code used to decode:-
char *enstr = new char[200];
strcpy(enstr,"sX3/ks3+abL5B1O/o/gSywOYv0tACnRkrMxKnBVDT7yhnatfE5ox2mvQz8RyM6MSCtf2exLUz3uIQGnTnk0yqgWzaDgR2ASEXi6ap1pV+1gAPMHBdiMZeNDI86RfleIH/37p7+lW3eyYwnpKJrsHf72jUu9R+aEXZSsEDEDQ1Hw=");
int len = strlen(enstr);
char *buff = (char *)malloc(len+1);
memset(buff,0,len+1);
BIO *biomem, *bio64;
bio64 = BIO_new( BIO_f_base64() );
BIO_set_flags(bio64,BIO_FLAGS_BASE64_NO_NL);
biomem = BIO_new_mem_buf(enstr,len);
biomem = BIO_push(bio64,biomem);
BIO_read(biomem,buff,len);
buff[len]='\0';
ofstream ofs("encoded.txt",std::ios::out);
ofs.write(buff,len);
ofs.close();
ofstream ofs("encoded.txt",std::ios::out);
ofs.write(buff,len);
ofs.close();
The ofstream will fiddle with bits, so you won't get the exact representation in memory. I believe you need:
ofstream ofs("encoded.txt", std::ios::binary);
binary stops new line processing.
When reading, I believe you will need:
ifstream ifs("encoded.txt", std::ios::binary);
ifs.unsetf(std::ios::skipws);
this will throw an error "RSA_EAY_PRIVATE_DECRYPT data greater than mod".
This means the number of bits in the message exceeds the number of bits in the modulus. To proceed, reduce the size of the message so that its less than or equal to n - 1, where n is the modulus.
Using encoded.txt file I'm unable to decrypt the string, Please help me on solving this
Where is your decryption code?
If you look in <openssl source>/apps/rsautil.c, then you will see how OpenSSL does it. All the utilities (`encrypt, decrypt, x509, smime, etc) have a corresponding source file, and they are located in <openssl source>/apps.
Here's the meat and potatoes of what openssl rsautil is doing after it sets up the options from the command line. See around line 275:
switch(rsa_mode) {
case RSA_VERIFY:
rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
break;
case RSA_SIGN:
rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
break;
case RSA_ENCRYPT:
rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
break;
case RSA_DECRYPT:
rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
break;
}
...