openssl Diffie Hellman public key to pem - c

I'm buiding a system using openssl.
We're going to use Diffie Hellman to share information between parties.
I had been able to create a DH using openssl.
Now I want to send the public key to the client using PEM format but I cannot find any function to convert DH public key to PEM format.
Anyone knows how to do this conversion?
Here you have the code I use to generate the DH structure:
BIGNUM * p = NULL, * g = NULL;
//Create DH MOD Group
DH * dh = dh_new_group14();
if (!dh)
puts("DH_new failed");
//Check everything is OK
int codes = 0;
if (!DH_check(dh, &codes))
puts("DH_check failed");
//Generate DH key
if (!DH_generate_key(dh))
puts("DH_generate_key failed");
I'm also capable of building a ASN1_INTEGER structure, but again I cannot find any function to generate the PEM from this structure.

Ok, I think I'm getting close.
I've managed to get an example with Java and what it generates is:
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.3.1
SEQUENCE {
INTEGER 0x00ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff
INTEGER 0x02 (2 decimal)
}
}
BITSTRING 0x0282010100b9c13521bc982e69de3e139d2521f32187ca932fdb579344c37cf2a8effb1c589ac27446656c911aefb84c961be5c389cabae7012b9edbec439ce5b57df4ad427e8baaa334c18c8bbf0fc3b19b197d484ae174f3fb538183368cdb11ecc228fc3fbb0029ff9aa0c06ccebbba47c1d1208410e9506cc08ae3bdc71924e95ae74994268822637ad628af95cf8b09cba0e070c7a8126921f6a700792ef45d844b8812f4d67f19bbc809ad33ac1ea59f4e3a9542e26b3a5f1738de6b9f8092c5a323747a716f39a17f879b87981c00944c8e5fb8f1e4d5ace6c81c182f80711bc55865c8562688b7084ae42f706fb80081f9e97982ef0242df221b202cee9b9ffcaf : 0 unused bit(s)
}
But what I get using PEM_write_bio_DHparams is almost the same but without the BITSTRING and the OBJECTIDENTIFIER.
SEQUENCE {
INTEGER 0x00ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff
INTEGER 0x02 (2 decimal)
}
Any clue about where's the problem?
I've seen that Java version generates a X.509 certificate to send the data, maybe I should generate a X509 certificate from the DH on my c++ version?

I think public keys are stored not alone but inside certificate request (csr) or certificate. So, you can use either PEM_write_bio_X509_REQ() or PEM_write_bio_X509() to store them in PEM format. Results will:
Certificate Request:
Data:
Version: 0 (0x0)
Subject: CN=DH Server Certificate (DSA-signed)
Subject Public Key Info:
Public Key Algorithm: dhKeyAgreement
PKCS#3 DH Public-Key: (1024 bit)
public-key:
00:ad:0c:c3:73:26:1b:68:2e:b2:1f:36:0c:eb:3c:
0b:bb:62:b2:fd:ac:8a:92:97:b9:79:6f:1a:f9:2e:
20:21:ff:fd:c4:e2:70:2a:62:ad:62:fc:67:d8:33:
58:09:19:8f:92:a3:b8:5b:41:30:d7:a9:b9:49:01:
07:24:76:ec:f9:88:e6:58:4e:a7:21:83:a4:a8:18:
4e:9a:ca:c5:14:04:9d:85:65:ee:7b:6a:59:80:af:
5e:fd:56:34:3e:95:34:14:64:0c:99:2e:c7:cc:4d:
9f:60:0f:a2:18:60:80:fe:6f:ed:4a:45:f3:4e:49:
97:42:a2:ec:86:c4:fd:5e:e9
prime:
00:e6:7f:e7:4b:4c:5a:55:bf:5e:2d:42:5d:17:62:
f0:6f:ff:d2:55:3f:18:a1:9e:51:02:34:ac:2b:64:
1b:c6:07:5f:ea:02:4f:f0:31:ed:71:ad:06:21:47:
4b:36:2a:65:a0:2a:dc:fb:3a:6f:24:6f:fc:4a:67:
0a:50:eb:6d:73:a3:35:fd:6a:d8:2d:68:b4:f2:c5:
c1:0b:6e:a1:5a:49:47:d6:bc:ab:9c:3f:d2:7a:7b:
2a:cf:be:2b:34:7e:0c:4f:00:0d:20:3e:83:6e:f3:
6c:65:f6:f0:f5:2a:5d:5f:1a:f2:c1:86:b6:0c:44:
19:1e:b0:66:ee:ea:eb:83:73
generator: 2 (0x2)
Attributes:
a0:00
Signature Algorithm: itu-t
-----BEGIN CERTIFICATE REQUEST-----
MIIBZDCCAVgCAQAwLTErMCkGA1UEAxMiREggU2VydmVyIENlcnRpZmljYXRlIChE
U0Etc2lnbmVkKTCCASAwgZUGCSqGSIb3DQEDATCBhwKBgQDmf+dLTFpVv14tQl0X
YvBv/9JVPxihnlECNKwrZBvGB1/qAk/wMe1xrQYhR0s2KmWgKtz7Om8kb/xKZwpQ
621zozX9atgtaLTyxcELbqFaSUfWvKucP9J6eyrPvis0fgxPAA0gPoNu82xl9vD1
Kl1fGvLBhrYMRBkesGbu6uuDcwIBAgOBhQACgYEArQzDcyYbaC6yHzYM6zwLu2Ky
/ayKkpe5eW8a+S4gIf/9xOJwKmKtYvxn2DNYCRmPkqO4W0Ew16m5SQEHJHbs+Yjm
WE6nIYOkqBhOmsrFFASdhWXue2pZgK9e/VY0PpU0FGQMmS7HzE2fYA+iGGCA/m/t
SkXzTkmXQqLshsT9XumgADADBgEAAwEA
-----END CERTIFICATE REQUEST-----
and
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 1407830109 (0x53e9c85d)
Signature Algorithm: dsaWithSHA1
Issuer: CN=DSA Server Certificate
Validity
Not Before: Aug 12 07:55:14 2014 GMT
Not After : Aug 9 07:55:14 2024 GMT
Subject: CN=DH Server Certificate (DSA-signed)
Subject Public Key Info:
Public Key Algorithm: dhKeyAgreement
PKCS#3 DH Public-Key: (1024 bit)
public-key:
00:ad:0c:c3:73:26:1b:68:2e:b2:1f:36:0c:eb:3c:
0b:bb:62:b2:fd:ac:8a:92:97:b9:79:6f:1a:f9:2e:
20:21:ff:fd:c4:e2:70:2a:62:ad:62:fc:67:d8:33:
58:09:19:8f:92:a3:b8:5b:41:30:d7:a9:b9:49:01:
07:24:76:ec:f9:88:e6:58:4e:a7:21:83:a4:a8:18:
4e:9a:ca:c5:14:04:9d:85:65:ee:7b:6a:59:80:af:
5e:fd:56:34:3e:95:34:14:64:0c:99:2e:c7:cc:4d:
9f:60:0f:a2:18:60:80:fe:6f:ed:4a:45:f3:4e:49:
97:42:a2:ec:86:c4:fd:5e:e9
prime:
00:e6:7f:e7:4b:4c:5a:55:bf:5e:2d:42:5d:17:62:
f0:6f:ff:d2:55:3f:18:a1:9e:51:02:34:ac:2b:64:
1b:c6:07:5f:ea:02:4f:f0:31:ed:71:ad:06:21:47:
4b:36:2a:65:a0:2a:dc:fb:3a:6f:24:6f:fc:4a:67:
0a:50:eb:6d:73:a3:35:fd:6a:d8:2d:68:b4:f2:c5:
c1:0b:6e:a1:5a:49:47:d6:bc:ab:9c:3f:d2:7a:7b:
2a:cf:be:2b:34:7e:0c:4f:00:0d:20:3e:83:6e:f3:
6c:65:f6:f0:f5:2a:5d:5f:1a:f2:c1:86:b6:0c:44:
19:1e:b0:66:ee:ea:eb:83:73
generator: 2 (0x2)
Signature Algorithm: dsaWithSHA1
r:
30:1c:1d:8a:87:b3:83:de:b2:4b:a4:1c:69:71:a1:
93:ae:1b:c0:30:0e:e0:b1:94:eb:92:da:e8:3b:12:
8c:59
s:
36:14:4c:fd:ce:a3:de:ef:6a:ac:49:45:b3:69:7d:
bf:98:72:9a:b0:6c:7b:59:bc:80:ee:96:32:a6:a3:
e8:e0
-----BEGIN CERTIFICATE-----
MIIB/zCCAacCBFPpyF0wCQYHKoZIzjgEAzAhMR8wHQYDVQQDExZEU0EgU2VydmVy
IENlcnRpZmljYXRlMB4XDTE0MDgxMjA3NTUxNFoXDTI0MDgwOTA3NTUxNFowLTEr
MCkGA1UEAxMiREggU2VydmVyIENlcnRpZmljYXRlIChEU0Etc2lnbmVkKTCCASAw
gZUGCSqGSIb3DQEDATCBhwKBgQDmf+dLTFpVv14tQl0XYvBv/9JVPxihnlECNKwr
ZBvGB1/qAk/wMe1xrQYhR0s2KmWgKtz7Om8kb/xKZwpQ621zozX9atgtaLTyxcEL
bqFaSUfWvKucP9J6eyrPvis0fgxPAA0gPoNu82xl9vD1Kl1fGvLBhrYMRBkesGbu
6uuDcwIBAgOBhQACgYEArQzDcyYbaC6yHzYM6zwLu2Ky/ayKkpe5eW8a+S4gIf/9
xOJwKmKtYvxn2DNYCRmPkqO4W0Ew16m5SQEHJHbs+YjmWE6nIYOkqBhOmsrFFASd
hWXue2pZgK9e/VY0PpU0FGQMmS7HzE2fYA+iGGCA/m/tSkXzTkmXQqLshsT9Xukw
CQYHKoZIzjgEAwNHADBEAiAwHB2Kh7OD3rJLpBxpcaGTrhvAMA7gsZTrktroOxKM
WQIgNhRM/c6j3u9qrElFs2l9v5hymrBse1m8gO6WMqaj6OA=
-----END CERTIFICATE-----

Have a look at what is done by the PEM_write_bio_DHparams() function, I think it does what you want.
[Edit: sorry, wrong function the first time]

Try this;
EVP is used for generic keys (keypairs)
BIO *b;
b = BIO_new(BIO_s_file());
BIO_set_fp(b, stdout, BIO_NOCLOSE);
EVP_PKEY *key = EVP_PKEY_new();
EVP_PKEY_assign_DH(key, DHAlice);
PEM_write_bio_PUBKEY(b, key);

Related

How to fetch SSL cert subject, issuer, start date and expire date from the trust.p12 cert file

Environment - IBM websphere application server 8.5.5
File - trust.p12 and key.p12 (in trust.p12 , 20 certificates are
added)
by using openssl commnd, i can able to see complete certificate
details like below
MAC Iteration 2048 MAC verified OK PKCS7 Encrypted data:
pbeWithSHA1And40BitRC2-CBC, Iteration 2048 Certificate bag Bag
Attributes
localKeyID: XX XX XX XX XX XX XX XX XX XX XX XX XX 48 54 A0 47 88 1D 90
friendlyName: test-server subject=/C=US/ST=IC/L=test/O=XXX Security/OU=XXX/CN=something1 issuer=/C=US/ST=IC/L=test/O=XXX
Security/OU=XXXX/CN=something1
-----BEGIN CERTIFICATE----- ... ... ...
-----END CERTIFICATE-----
Certificate bag Bag Attributes
localKeyID: XX XX XX XX XX XX XX XX
friendlyName: root subject=/C=US/ST=IC/L=test/O=XXX /OU=XXX/CN=testroot issuer=/C=US/ST=IC/L=test/O=XXX
/OU=XXXX/CN=testroot
-----BEGIN CERTIFICATE----- ... ... ...
-----END CERTIFICATE-----
But i tried to fetch subject, issuer, start date and expire date from
the trust.p12 cert file by using below commands.
1st Method
openssl pkcs12 -in trust.p12 -nokeys | openssl x509 -noout
-dates -subject -issuer -alias
2nd Method
openssl pkcs12 -in trust.p12 -out trust.pem -nodes
cat trust.pem | openssl x509 -noout -enddate
however i'm getting output for 1 certificate alone instead of 20
certificates trough above commands.
1) Is there any other way to fetch 20 certificate one by one something
like by passing alias name?
2) How to fetch subject, issuer, start date and expire date for 20 certificate one by one?
How about, if this could be done in java. You need to know the alias for all the 20 certificates and defined it as a string array.
Also you define alias as a config file so that if alias changes in future, you don't have to change the code.
static List<X509Certificate> certList = new ArrayList<>();
public static void main(String[] args) throws KeyStoreException
{
String[] alias = { "1","2"};
KeyStore keyStore = getKeyStore();
for (int i = 0; i < alias.length; i++) {
X509Certificate certFromKeyStore = (X509Certificate) keyStore.getCertificate(alias[i]);
System.out.println(certFromKeyStore.getSubjectDN());
certList.add(certFromKeyStore);
}
for (X509Certificate x509 : certList) {
// verify all the information you looking for
System.out.println(x509.getSerialNumber() + " "+ x509.getIssuerDN() );
}
}
public static KeyStore getKeyStore()
{
KeyStore keyStore = null;
try
{
keyStore = KeyStore.getInstance("PKCS12");
InputStream input = new FileInputStream("PATHTOP12");
keyStore.load(input, "YOUR_P12_PASSWORD".toCharArray());
} catch (Exception e)
{
// catch the exception
}
return keyStore;
}
Let me know if this helps.
Are you specifically looking this to be done in openssl ?

objectSID coming back in non-standard format

I'm using JNDI to query Active directory from group catalog servers:
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://" + serverUrl + "/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, userName + "#" + currentDomain);
env.put(Context.SECURITY_CREDENTIALS, credentials);
env.put("java.naming.ldap.attributes.binary", "objectSid");
// Create the initial context
DirContext ctx = new InitialDirContext(env);
When I get objectSid back and convert the byte[] to hex string I get sids such as:
HEX: ACED0005757200025B42ACF317F8060854E002000078700000001001020000000000052000000025020000
SID: S-172-23445241858-4088152667-134674455-188500-7370752-17825792-2-537198592-620756992
This results in byte 0 having a value of 172 and byte 1 of 237, as well as 3 bytes at the end of parsing the 4 byte sub authorities.
Byte 0 should always be 1 and byte 2 should be the number of 4 byte sub authority identifiers (in this case 9). I'm having trouble figuring out what's going on as I'm unable to correctly map between expected and actual.
I'm betting there's some newbie mistake that I'm making, but can't figure out what it might be; my hope is that someone out there has been through this and can tell me what it is!
This was actually not an LDAP issue, but an issue with writing the object I was getting back to a byte array. The lesson is, debug harder...

CMS (PKCS#7) RecipientInfo

I am actually working on a function which should extract RecipientInfo from PKCS7 mime encrypted message. The reason why I want to do this is, that I want to get all mail addresses (or at least the keyids/fingerprints) the message is encrypted for.
Well - I tried something out and created something like this (indata is a *.p7m attachment content, indata_len the strlen of indata):
char *indata;
int indata_len, i;
PKCS7 *p7 = NULL;
BIO *bcont = NULL;
CMS_ContentInfo *cms = NULL;
STACK_OF(CMS_RecipientInfo) *recipients = NULL;
CMS_RecipientInfo *recip = NULL;
BIO *encMessage = BIO_new(BIO_s_mem());
if (encMessage == NULL) {
goto clean_exit;
}
if(!BIO_write(encMessage, indata, indata_len)) {
goto clean_exit;
}
cms = SMIME_read_CMS(encMessage,NULL);
if (cms == NULL ) {
goto clean_exit;
}
recipients = CMS_get0_RecipientInfos(cms);
if (recipients == NULL) {
goto clean_exit;
}
for (i=0; i< sk_CMS_RecipientInfo_num(recipients); i++) {
recip = sk_CMS_RecipientInfo_value(recipients, i);
if( recip == NULL || CMS_RecipientInfo_type(recip) != CMS_RECIPINFO_TRANS ) {
continue;
}
int r;
ASN1_OCTET_STRING **keyid;
X509_NAME **issuer;
ASN1_INTEGER **sno;
r = CMS_RecipientInfo_ktri_get0_signer_id(recip, keyid, issuer, sno);
if (!r) {
continue;
}
printf("Key: %s\n", keyid);
}
I get no error (checked with ERR_get_error()) but keyid, issuer and sno stay "null", output of above code is:
Key: (null)
So my question is, is it even possible to get that information of an encrypted message or is there just an error in reasoning on my side?
If it is possible to get that data, can someone give me a hint?
If it is not possible, whats the default (best) way to check which private key to use for decryption. Since there can be more than one S/Mime certificate/key for a single user. E.g. creating new key since the old one is lost or just get a new cert/key combination from provider, ...
Imho, looping through all keys could take some time if the message is really big.
Best regards,
Max
I don't know how to fix your code, but I have a couple of openssl commands and a python script to solve your task:
You can run the following command to get the list of all serial numbers
of the recipient keys in an encrypted file MYMAIL:
openssl smime -pk7out -inform DER -in MYMAIL \
| openssl pkcs7 -noout -print \
| grep serial
This will print the serial number as decimal numbers of all recipients, i.e. serial numbers of certificates for which the file MYMAIL has been encrypted for. For a given certificate file CERTFILE.0, the command
openssl x509 -in CERTFILE.0 -serial -noout
prints its serial number as a hexadecimal number. Now, you can to combine the serial numbers of the certificates you have with the serial numbers mentioned in MYMAIL.
I've wrote a python script that does this and that can be used to replace the default smime_decrypt_command in mutt, such that when decrypting an E-Mail, the correct private key is chosen for decryption: https://github.com/t-wissmann/dotfiles/blob/master/utils/smime-recipient-list.py
For the case that the url breaks, I'm pasting the entire script below.
#!/usr/bin/env python3
"""
Given an smime encrypted file and some smime certificates,
tell for which of the smime certificates, the encrypted file has been
encrypted for.
"""
import argparse
import os
import re
import subprocess
import sys
import textwrap
class Openssl:
def __init__(self, openssl_command):
self.openssl_command = openssl_command
def get_certificate_serial_number(self, certificate_file):
"""Given a certificate_file filepath, return its serial number as an int"""
command = [self.openssl_command, 'x509', '-in', certificate_file, '-serial', '-noout']
proc = subprocess.run(command, stdout=subprocess.PIPE)
# output should be of the form 'serial=HEXADECIMALNUMBER'
try:
return int(proc.stdout.decode().replace('serial=', ''), 16)
except ValueError:
print("Can not read file: {}".format(certificate_file), file=sys.stderr)
def smime_pk7out(self, encrypted_file):
"""run smime -pk7out, return its output"""
command = [self.openssl_command, 'smime', '-pk7out']
command += ['-inform', 'DER', '-in', encrypted_file]
proc = subprocess.run(command, stdout=subprocess.PIPE)
return proc.stdout.decode()
def pkcs7_serial_numbers(self, pk7buf):
"""extract all serial numbers via openssl pkcs7 -noout -print"""
command = [self.openssl_command, 'pkcs7', '-noout', '-print']
proc = subprocess.run(command, stdout=subprocess.PIPE, text=True, input=pk7buf)
for match in re.finditer('serial: ([0-9]+)', proc.stdout):
yield int(match.group(1))
def list_recipient_serial_numbers(self, encrypted_file):
"""Do essentially:
openssl smime -pk7out -inform DER -in MYMAIL \
| openssl pkcs7 -noout -print \
| grep serial
"""
pk7out = self.smime_pk7out(encrypted_file)
return list(self.pkcs7_serial_numbers(pk7out))
def smime_decrypt(self, private_key, certificate, filepath, passin='stdin'):
"""encrypt the given filepath and print to stdout"""
command = [self.openssl_command, 'smime', '-decrypt', '-passin', passin]
command += ['-inform', 'DER', '-in', filepath]
command += ['-inkey', private_key]
command += ['-recip', certificate]
subprocess.run(command)
def main():
"""main"""
description = "Detect recipients of smime encrypted files"
epilog = textwrap.dedent(r"""
E.g. you can decrypt an email with the command that picks the
private key automatically:
{} \
--passin stdin --decrypt \
--private-key ~/.smime/keys/* \
-- mymail ~/.smime/certificates/*
If you use mutt, you can set
set smime_decrypt_command="\
~/path/to/smime-recipient-list.py --passin stdin --decrypt \
--private-key ~/.smime/keys/* \
-- %f ~/.smime/certificates/KEYPREFIX.*"
where KEYPREFIX is the prefix of your key (i.e. without the .0 or .1 suffix).
""".format(sys.argv[0]))
parser = argparse.ArgumentParser(
description=description,
epilog=epilog,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('encryptedfile', help='the encrypted file')
parser.add_argument('certificates',
nargs='+',
help='the smime certificate files')
parser.add_argument('--openssl', default='openssl', help='openssl command name')
parser.add_argument('--list-serials', action='store_true',
help='list serial numbers of certifacts')
parser.add_argument('--print-path', action='store_true',
help='print path of recipient certificates')
parser.add_argument('--private-keys', nargs='*', default=[], help='private keys for decrypt')
parser.add_argument('--decrypt', action='store_true',
help='decrypt using one of the private keys passed.\
the key must have the same file name as the certificate.')
parser.add_argument('--passin', default='stdin',
help='default openssl -passin parameter for decrypt')
args = parser.parse_args()
openssl = Openssl(args.openssl)
# get the serial number of every smime-certfile:
serialnum2cert = {}
for i in args.certificates:
serialnum2cert[openssl.get_certificate_serial_number(i)] = i
if args.list_serials:
for serialnum, keyfile in serialnum2cert.items():
print("{} --> {}".format(keyfile, serialnum))
recipients = openssl.list_recipient_serial_numbers(args.encryptedfile)
if args.print_path or args.decrypt:
matching_keys = []
for i in recipients:
if i in serialnum2cert:
matching_keys.append(serialnum2cert[i])
if args.print_path:
for i in matching_keys:
print(i)
if args.decrypt:
private_keys = {}
for filepath in args.private_keys:
private_keys[os.path.basename(filepath)] = filepath
key_found = None
for fp in matching_keys:
if os.path.basename(fp) in private_keys:
priv_key_path = private_keys[os.path.basename(fp)]
# print("We can use {} and {}".format(priv_key_path, fp))
key_found = (priv_key_path, fp)
if key_found is None:
print("No matching private key found.", file=sys.stderr)
sys.exit(1)
openssl.smime_decrypt(key_found[0], key_found[1],
args.encryptedfile, passin=args.passin)
if __name__ == "__main__":
main()

OMA DM1.2 md5 digest calculation

I am implementing a server for communication using the OMA DM 1.2 SyncML protocol and reffers to the OMA Device Management Security document. I am having issues with authentication. The client sends a challenge to the server as:
<Chal>
<Meta>
<Format xmlns="syncml:metinf">b64</Format>
<Type xmlns="syncml:metinf">syncml:auth-md5</Type>
<NextNonce xmlns="syncml:metinf">RLLe7tWM313qHMq9ooUZUPJX0RqU9mEZuyoVF+jXhqQ=</NextNonce>
</Meta>
</Chal>
I then calculate the md5-digest to return to the device using the java code, where nonce is the Base64 string in "NextNonce" in challenge above:
MessageDigest digest = MessageDigest.getInstance("MD5");
String usrPwd = username + ":" + password;
String usrPwdHash = Base64.encodeBase64String(digest.digest(usrPwd.getBytes("utf-8")));
String usrPwdNonce = usrPwdHash + ":" + nonce;
String usrPwdNonceHash = Base64.encodeBase64String(digest.digest(usrPwdNonce.getBytes("utf-8")));
return usrPwdNonceHash;
Then this hash is returned to the device as:
<Cred>
<Meta>
<ns2:Type>syncml:auth-md5</ns2:Type>
<ns2:Format>b64</ns2:Format>
</Meta>
<Data>QpbMtvvfNGRIavJ0jqcxaw==</Data>
</Cred>
But the device returns with a status 401 and a new challenge. Is there something wrong with how i calculate the md5-hash or must there be some other issue?
Found my error. The nonce should be the decoded Base64 string value, not the Base64 string.
nonce = new String(Base64.decodeBase64("RLLe7tWM313qHMq9ooUZUPJX0RqU9mEZuyoVF+jXhqQ="), "utf-8");

Programmatically input data in X509 Certificate using OpenSSL

I am trying to create a ecdsa certificate but I would like to generate it programatically. I am using openssl and C programming.
When I generate a certificate from the command line multiple questions are asked me to answer in other to use in the certificate.
I would like to know how to define this questions, input this data programatically.
This is what I have found on the web, but I don't understand how to insert more information and this really works:
X509 *x;
x=X509_new();
X509_NAME *name = X509_get_subject_name(x);
X509_set_version(x, 2);
ASN1_INTEGER_set(X509_get_serialNumber(x), 3);
X509_gmtime_adj(X509_get_notBefore(x), 0);
X509_gmtime_adj(X509_get_notAfter(x), (long) 60 * 60 * 24 * 365);
X509_set_pubkey(x, pk);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (const unsigned char*) "PT", -1, -1, 0);
The X509_NAME_add_entry_by_txt function I realise it's the answer to the country, but what does this "C" means? How is this function composed? Can I put whatever I want in the place of "C" and in the place of "PT"?
The C is the standard way of denoting the country and PT is the correct selection for Portugal (see this list for other country options).
You can use the X509_NAME_add_entry_by_txt function to set other values in the distinguished name, using the correct prefix:
C = country
ST = state
L = locality
O = organisation
OU = organisational unit
CN = common name
Only the country field has a fixed range of choices.
See also the example given on the manual page: http://www.openssl.org/docs/crypto/X509_NAME_add_entry_by_txt.html#EXAMPLES

Resources