Hi Kyle H,

Thanks for your reply.

I am sorry for giving so less information.

Here are some of the details you asked for.

What is the version of OpenSSL that you're using?
  - 1.0.1e

What is the version of BouncyCastle that you're using?
  - BC => 1.45

Have you ensured that the private key to the certificate you're using is
available in every place you're trying to decrypt it?
 - Yes. Because BC Encrypted mails get decrypted in all those places.

Can you decrypt the mail with OpenSSL in the place where you have encrypted
it (not using the command line, but using the API)?
 - Yes.

Can you encrypt with BouncyCastle and have OpenSSL decrypt it?
 - Yes.

What are the error messages (or exceptions) you're receiving?
 - None. I do not have access to server error logs.

What is the command line that you're using to decrypt it?  What is the code
you're using to encrypt the mail?  What is the code you're using to decrypt
the mail?
I will be posting snippets of both Java Side and Native Side code for
encryption and decryption.
   - *Encryption Code*
*        Java Code*
*               //*inputData this is a temporary mime file created for
encryption.
try {
fis = new FileInputStream(inputData);
OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(fis);
long bioRef = NativeCrypto.create_BIO_InputStream(bis);
 int certsRefArrLength = recipientCertificates.length;
long certsRefArr[] = new long[certsRefArrLength];
for (int i = 0; i < certsRefArrLength; i++) {
byte arr[] =
android.security.Credentials.convertToPem(recipientCertificates[i]);
                                *//You might not have access to "*
*android.security.Credentials"*
            InputStream certIs = new  ByteArrayInputStream(arr);
            OpenSSLX509Certificate openSSLcert =
OpenSSLX509Certificate.fromX509PemInputStream(certIs);
             byte openSSLcertEncoded[] = openSSLcert.getEncoded();
             certsRefArr[i] = NativeCrypto.d2i_X509(openSSLcertEncoded);
}
 String outputFilePath = output.getAbsolutePath();
 return PKCS7encrypt(bioRef, certsRefArr, outputFilePath,
encryptionAlgorithm);
 } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (CertificateEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

*        Native Code*
JNIEXPORT jboolean JNICALL Java_xyz_MainActivity_PKCS7encrypt(JNIEnv *env,
jobject thiz, jlong bioRef, jlongArray certRef, jstring joutfile, jstring
jcipher) {
BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
const EVP_CIPHER *cipher = NULL;

const char* nativeOutFile = env->GetStringUTFChars(joutfile, 0);

const char *nativeCipher = env->GetStringUTFChars(jcipher, 0);
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nEVP_rc2_40_cbc");
cipher = EVP_rc2_40_cbc();
        //Selecting EVP_rc2_40_cbc() by default just for testing purpose.

int flags = PKCS7_STREAM;
STACK_OF(X509) *certs = NULL;

if(certRef != NULL) {
certs = sk_X509_new_null();
jsize s = env->GetArrayLength(certRef);
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nSize of array: %d",
s);
int i = 0;
jlong *c = env->GetLongArrayElements(certRef, 0);
for (; i < s; i++) {
long cVal = c[i];
//printf("\nAddress of cert[%d]: %l", i, cVal);
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nAddress of
cert[%d]: %lu", i, cVal);
X509* certRef = reinterpret_cast<X509*>(static_cast<uintptr_t>(cVal));
sk_X509_push(certs, certRef);
}
}
PKCS7* p7 = PKCS7_encrypt(certs, bio, cipher, flags);
if (p7 != NULL) {
FILE *outfile = fopen(nativeOutFile, "w");
BIO* out = BIO_new_fp(outfile, BIO_NOCLOSE) ;// BIO_new_file(outfile, "");
int r = SMIME_write_PKCS7(out, p7, bio, flags);
if(r == 1) {
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nSuccess for
SMIME_write_PKCS7");
} else {
printError();
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nFailure for
SMIME_write_PKCS7");
return false;
}
fclose(outfile);
return true;

}
else {
printError();
return false;
}
}
// I am trying to decrypt the file generated at the end of this function in
with the below mentioned command and code. It works.!

*   - Decryption Command*
           *openssl smime -decrypt -in encrypted_file -recip mycert.pem >
decrypted_file.txt*

*   - Decryption Code*
*          JAVA Code*
try {
String inFile = "/storage/sdcard0/openssl_enc_header_align_mime";
Log.i(TAG, "Experimenting with X509Certificates.");
KeyStore tempKeyStore = KeyStore.getInstance("PKCS12");
                        tempKeyStore.load(null, mPassword.toCharArray());

tempKeyStore.setKeyEntry(mAlias,privateKey,mPassword.toCharArray(), chain);
                        X509Certificate cert =
(X509Certificate)tempKeyStore.getCertificate(mAlias); //3
                        byte arr[] =
android.security.Credentials.convertToPem(cert);
                        InputStream certIs = new  ByteArrayInputStream(arr);
                        OpenSSLX509Certificate openSSLcert =
OpenSSLX509Certificate.fromX509PemInputStream(certIs);
                        byte openSSLcertEncoded[] =
openSSLcert.getEncoded();
                        long certRef =
NativeCrypto.d2i_X509(openSSLcertEncoded);
         OpenSSLKey oKey = OpenSSLKey.fromPrivateKey(privateKey);
        long evpKeyRef = oKey.getPkeyContext();

        String outfile = "/storage/sdcard0/decrypt_output.txt";

        int flags = 0;

        int ret = PKCS7decrypt(inFile, evpKeyRef, certRef, outfile, flags,
23, 54);
        Log.i(TAG, "Decrypt Returns: " + ret);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

*          Native Code*
JNIEXPORT int JNICALL Java_xyz_MainActivity_PKCS7decrypt(JNIEnv *env,
jobject thiz, jstring inFile, jlong pKeyRef, jlong certRef, jstring
outfile, jint flags, jint a, jint b) {

const char* nativeInFile = env->GetStringUTFChars(inFile, 0);
const char* nativeOutFile = env->GetStringUTFChars(outfile, 0);
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\npKeyRef: %lu",
(long)pKeyRef);
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\ncertRef: %lu",
(long)certRef);
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nbioRef: %s",
nativeOutFile);
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nflags: %lu",
(long)flags);

PKCS7 *p7;// = SMIME_read_PKCS7(input, NULL);
EVP_PKEY *pKey = reinterpret_cast<EVP_PKEY
*>(static_cast<uintptr_t>((long)pKeyRef));
X509* cert = reinterpret_cast<X509*>(static_cast<uintptr_t>((long)certRef));

//FILE *fp
BIO *in = BIO_new_file(nativeInFile, "r");
p7 = SMIME_read_PKCS7(in, NULL);

FILE *fp = fopen(nativeOutFile, "w");
BIO* out = BIO_new_file(nativeOutFile, "w");
int flgs = 0;

int res = PKCS7_decrypt(p7, pKey, cert, out, flgs);
int biof = BIO_flush(out);
if(biof != 1) {
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nBio_flush
failure.");
} else {
__android_log_print(ANDROID_LOG_DEBUG, "OpenSSLJni", "\nBio_flush
success.");
}
if(res) {
return (int)a + (int)b;
} else {
printError();
return -1;
}
}

Is there anything else that you can think of that might help identify where
the problem actually is?



On Tue, Jun 3, 2014 at 3:13 AM, Kyle Hamilton <aerow...@gmail.com> wrote:

> My understanding from what you're saying is that you can successfully
> encrypt with OpenSSL, but BouncyCastle is failing to decrypt it.
>
> What is the version of OpenSSL that you're using?
> What is the version of BouncyCastle that you're using?  What version of
> javamail are you using with it?
> Which crypto library is the server is using, and what version?
> Have you ensured that the private key to the certificate you're using is
> available in every place you're trying to decrypt it?
> Can you decrypt the mail with OpenSSL in the place where you have
> encrypted it (not using the command line, but using the API)?
> Can you encrypt with BouncyCastle and have OpenSSL decrypt it?  What kind
> of keypair and certificate are you using?  What tool was used to create
> it?  Does the certificate chain verify?
> What are the error messages (or exceptions) you're receiving?
> What is the command line that you're using to decrypt it?  What is the
> code you're using to encrypt the mail?  What is the code you're using to
> decrypt the mail?
>
> Is there anything else that you can think of that might help identify
> where the problem actually is?
>
> BouncyCastle relies on javamail for mail parsing.  You may need to include
> email headers and wrap the entire thing in a MIME-formatted wrapper to
> avoid choking javamail.  If this is the case, I perceive it is a bug in
> BouncyCastle, as it explicitly exceeds the scope of the BER structures that
> CMS and prior S/MIME versions work with.  I also perceive it as not a bug
> in OpenSSL, for the same reason.
>
> -Kyle H
>
>
>
> On Mon, Jun 2, 2014 at 2:30 AM, Yash Dosi <yashd...@gmail.com> wrote:
>
>>
>> Hi All,
>>
>> I am trying to replace Bouncy Castle with OpenSSL for some of the
>> operation in my android app.
>>
>> Right now, I can successfully encrypt a mail using OpenSSL and send it.
>> But the problem comes when you are trying to decrypt the same email. I
>> cant decrypt it on both the server as well as using bouncy castle.
>>
>> I am using the same certificate for both encryption and decryption. And
>> when I try to decrypt OpenSSL encrypted content using OpenSSL Command Line,
>> I dont face any problem.
>>
>> Any ideas what could be the issue?
>>
>> --
>> Yash Dosi.
>>
>>
>

Reply via email to