Parsing the PEM Certificate output into JSON - c++

I've got a PEM certificate that's been decoded for me via CLI/REST (see: https://support.sonus.net/display/SBXDOC111/Request+System+-+CLI under the pki command).
If the API/commands allowed for the PEM certificate string still encoded I could use openSSL directly and just decode it myself.
Due to the Session Boarder Controller command decoding it for me, I'm looking for a parser. Much like the question asked at parse a PEM certificate into JSON I was wondering whether there's a C++ library that could take the string output and convert it into json or potentially create a class/structure that I can then serialize into the JSON format at my leasure.
I'm currently thinking that the easiest way of achieving something like this would be using regexes to take each important section of the output and store them into the structure/class that I would then serialize as needed. But to me that seems quite heavy handed although would achieve a desired result assuming the structure matches the example output every certificate attempted.
result Certificate:
Data:
Version: 1 (0x0)
Serial Number: 13211600523504912060 (0xb75908ad95e006bc)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, ST=MA, L=Westford, O=VeriSign
Validity
Not Before: Apr 28 09:56:54 2015 GMT
Not After : Jul 12 09:56:54 2033 GMT
Subject: C=IN, ST=TN, L=Chennai
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c5:80:dc:59:0a:8d:98:19:0b:bd:be:fd:ab:6c:
f7:e9:b6:28:d9:e8:fe:a5:84:fb:45:d9:16:97:f5:
fc:9f:df:7b:5b:03:6e:34:38:3f:10:2b:d0:d8:d6:
4a:03:5f:2a:78:85:4c:65:d4:0d:a6:e2:d3:be:1a:
fc:8b:96:a1:db:15:16:74:3e:9f:2a:34:95:88:6a:
49:3b:1e:78:15:bf:5c:e8:ec:a3:0d:8b:d4:2a:39:
d6:17:c1:a8:88:94:36:23:23:d5:3b:2c:49:fb:15:
d3:e6:7f:72:b0:e4:3d:e6:3a:44:f3:ac:a2:d3:2a:
62:f7:2f:d1:d4:a1:82:fe:03:57:49:1d:6b:12:14:
2c:28:f8:ef:6c:e0:c2:36:8c:7f:77:2a:32:d9:ce:
c7:9e:fc:4f:20:aa:43:db:b1:77:16:e9:d5:b5:44:
ff:06:8a:85:d4:74:63:af:3c:5e:f3:a3:e0:83:5a:
40:d1:5d:fc:84:36:34:b4:8b:ac:f1:5b:2c:b6:0e:
97:bc:1b:cd:a4:f8:17:b3:81:42:41:db:09:bb:79:
42:1f:92:dc:43:52:ca:78:e3:db:3d:db:e9:f6:39:
15:eb:3a:09:e5:ab:eb:18:5f:7e:14:ec:f9:b6:04:
9e:f5:6d:73:f4:ea:85:c4:4a:1f:5a:01:8f:2e:94:
b6:0d
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
1a:91:c0:8a:b8:66:4b:a2:67:bc:99:4f:b4:0b:f8:bc:67:0e:
de:23:37:42:bc:dd:96:64:7c:ef:e1:05:c7:eb:92:06:fa:ef:
7b:72:ee:7f:26:b5:1c:39:b5:f2:b2:04:6e:2e:0c:1d:7e:1f:
7a:87:b8:8b:9c:25:e2:8f:77:6f:ac:bb:a0:63:28:51:4f:7c:
35:30:ad:31:24:85:f3:99:6d:c2:f8:33:eb:49:45:ed:ab:26:
97:f4:04:a7:0a:06:dd:40:c3:f6:1a:0e:ec:72:0f:40:65:ab:
34:4a:dc:51:2b:f3:61:b6:3a:1c:26:09:a1:af:37:dc:bf:a5:
ba:dd
No Trusted Uses.
No Rejected Uses.
Alias: Server Cert
Key Id: 79:70:FC:99:1A:2B:15:A7:A1:33:21:F7:8A:57:0C:A7:07:7B:96:35

Related

EPP Server SSL_Read hang after greeting

I have strange problems in ssl_read/ssl_write function with EPP server
After connected I read greeting message successfully.
bytes = SSL_read(ssl, buf, sizeof(buf)); // get reply & decrypt
buf[bytes] = 0;
ball+= bytes;
cc = getInt(buf);
printf("header: %x\n",cc);
printf("Received: \"%s\"\n",buf+4);
First 4 bytes are 00, 00, 09, EB and read 2539 bytes in greeting message.
After that, all operations like hello or logins are hand when SSL_read();
xml= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><eppxmlns=\"urn:ietf:params:xml:ns:epp-1.0\"><hello/></epp>";
char bb[1000] = {0};
makeChar(strlen(xml)+4, bb);
memcpy(bb+4, xml, strlen(xml)+4);
bytes = SSL_write(ssl,xml,strlen(xml)+4);
usleep(500000); //sleep 0.5 sec
memset(buf, 0, 1024);
printf("read starting.\n");
bytes = SSL_read(ssl, buf, 1024); //always hang here
buf[bytes]=0;
printf("%d : %s", bytes, buf);
I am confused. I read RFC documentations but I can not find answer.
in EPP documentation, they said "In order to verify the identity of the secure server you will need the ‘Verisign Class 3 Public Primary Certification Authority’ root certificate available free from www.verisign.com".
is it important?
is it important?
Yes, as outlined in RFC 5734 "Extensible Provisioning Protocol (EPP) Transport over TCP", the whole security of an EPP exchange is bound to 3 properties:
access list based on IP address
TLS communication and verification of certificates (mutually, which is why you - as registrar aka client in EPP communication - have often to send in advance the certificate you will use ot the registry)
the EPP credentials used at <login> command.
Failure to properly secure the connection can mean:
you as registrar sending confidential information (your own EPP login, various details on domains you sponsor or not, including <authInfo> values, etc.) to a third party not being the registry
and in reverse, someone mimicking you in the eyes of the registry hence doing operations on which you will have to get the burden of, including financially for all domains bought, and legally.
But even in general for all cases of TLS handshake, if you want to be sure to be connected, as client, to the server you think you are, you need to verify its certificate.
Besides trivial things (dates, etc.), the certificate:
should at least be signed by an AC you trust (your choice who you trust)
and/or is a specific certificate with specific fingerprint/serial and other characteristics (but you will have to maintain that when the other party changes its certificate)
and/or matches DNS TLSA records
In short, if you are new to both EPP and TLS and C/C++ (as you state yourself in your other question about Verisign certificate), I hugely recommend you do not try to do all of this by yourself at a so low level (for example you should never manipulate XML as you do above, it shouldn't be a string. Again, there are libraries to properly parse and generate XML documents). You should use an EPP library that leverage most of the things for you. Your registry may provide an "SDK" that you can use, you should ask it.
PS: your read is probably hanging because you are not sending the payload in the correct fashion (again, something an EPP library will do for you). You need to send the length, as 4 bytes (which you need to compute after converting your string to bytes using the UTF-8 encoding), and then the payload itself. I am not sure this is what your code does. Also your reading part is wrong: you should first read 4 bytes from server, this will give you the length (but do note they can theoretically arrive not necessarily in a single packet so one "ssl read" might not give all 4 of them, you need a loop), after which you know the length of the payload you will get which allows you to set up proper buffers, if needed, as well as detecting properly when you received everything.

TLS errors using Chilkat library to access Microsoft Graph APIs

I've been trying to use Chilkat library to play around and learn about using Microsoft Graph APIs but it seems I keeps getting TLS errors (connectFailReason 109) with even the simplest GETs and POSTs. This is what a typical log looks like:
ChilkatLog:
QuickGetSb:
DllDate: May 29 2021
ChilkatVersion: 9.5.0.87
UnlockPrefix: XXXXXXXXXXXXXXXX
Architecture: Little Endian; 32-bit
Language: C++ Builder / clang / 32-bit
VerboseLogging: 0
Component successfully unlocked using purchased unlock code.
url: https://graph.microsoft.com/v1.0/users
httpRequestStr:
a_quickReq:
quickHttpRequest:
httpVerb: GET
url: https://graph.microsoft.com/v1.0/users
openHttpConnection:
Opening connection directly to HTTP server.
httpHostname: graph.microsoft.com
httpPort: 443
tls: True
socket2Connect:
connect2:
connectImplicitSsl:
clientHandshake:
clientHandshake2:
ProcessHelloRetryRequest:
readHandshakeMessages:
WindowsError: An existing connection was forcibly closed by the remote host.
WindowsErrorCode: 0x2746
maxToReceive: 5
Failed to receive data on the TCP socket
Failed to read beginning of SSL/TLS record.
b: 0
dbSize: 0
nReadNBytes: 0
idleTimeoutMs: 60000
--readHandshakeMessages
--ProcessHelloRetryRequest
--clientHandshake2
--clientHandshake
Client handshake failed. (3)
--connectImplicitSsl
connectFailReason: 109
ConnectFailReason: 109
--connect2
--socket2Connect
connect: Socket fatal error.
--openHttpConnection
--quickHttpRequest
--a_quickReq
--httpRequestStr
Failed.
--QuickGetSb
--ChilkatLog
The library is not the very latest version but it isn't TOO old (about a year and a half - version 9.5.0.86). I didn't want to upgrade just yet because I have some "live" projects using this dev box (and this is just a "learning journey") so I was wondering if anyone can tell me whether the library version is the most likely issue or whether, perhaps, I'm missing some simple settings in the CkHttp object - the only thing I really do with it is set the auth token (which seems to have been retrieved correctly judging from the logs I output.
The actual API calls are pretty straightforward - mostly simple (slightly modified) examples from Chilkat website. But even the simplest http.quickGetStr("https://graph.microsoft.com/v1.0/me"); fails with a log similar to the above.
So, if anyone can suggest any properties to set to ckHttp to solve this issue (or confirm that library needs to be upgraded to access graph.microsoft.com - if, indeed, that is the case) - I would greatly appreaciate it.
Marko
This problem is already fixed. Contact support#chilkatsoft.com to get a pre-release build for v9.5.0.92.

RSA Signature Size Mismatch

As stated here, the length of the message signature is equal to the modulus of the Private Key, aka the Public Key.
I'm implementing a system that signs a message, and I have a size mismatch that I can't solve.
I use crypto++.
Here is the code I use :
/* Create RSA Keys */
RSA::PrivateKey privateKey;
privateKey.GenerateRandomWithKeySize(prng, 3072);
RSA::PublicKey publicKey(privateKey);
cout << ">> RSA Keys generated";
/* Key Size */
string spki;
StringSink sSink(spki);
publicKey.Save(sSink);
cout <<" ("<< spki.size()<<" bytes)"<<endl;
RSASSA_PKCS1v15_SHA_Signer signer(privateKey);
size_t length = signer.MaxSignatureLength();
cout <<"MaxSignatureLength " <<length<<endl;
SecByteBlock signature( length );
And the output is :
>> RSA Keys generated (420 bytes)
>> ServerHello sent (436 bytes)
MaxSignatureLength 384
RSA Signature length 384
Shouldn't the MaxSignatureLength, and the RSA Signature length 420 bytes long ?
Is the problem with the algorithm I use ?
Shouldn't the MaxSignatureLength, and the RSA Signature length 420 bytes long ?
No. You are asking for a key with 3072-bits or 384 bytes. That's the limit on the size of the signature.
Each cryptosystem will likely be different in this area.
cout <<" ("<< spki.size()<<" bytes)"<<endl;
This is the size of {OID,n,e} with the ASN.1 framing or overhead. See your previous question Sending PublicKey within packet payload for what it looks like (in particular, the output of the command dumpasn1 rsa-public.der).
cout <<"MaxSignatureLength " <<length<<endl;
This is n - 1 for RSA, if I recall correctly.
Is the problem with the algorithm I use ?
No, you are doing things correctly by calling MaxSignatureLength().
>> RSA Keys generated (420 bytes)
>> ServerHello sent (436 bytes)
I'm just speculating, but it appears you appear to have design issues, too.
When you encrypt a message, like the ServerHello, you usually encrypt it under a symmetric cipher, like AES or Camellia. Then, you take that symmetric cipher key, and encrypt it under the RSA key. Finally, you send the pair {encrypted symmetric cipher key, encrypted message under symmetric cipher} to the other party.
In the system partially described above, you're only encrypting 16 or 32 bytes under the public key.
I think what you should be doing is using an Integrated Encryption Scheme to send encrypted message back and forth. For that, see Elliptic Curve Integrated Encryption Scheme (ECIES) and Discrete Logarithm Integrated Encryption Scheme (DLIES). ECIES operates over elliptic curves, and DLIES operate over integers.
Integrated Encryption Schemes have some very desireable security properties, like they are IND-CCA2. They achieve it by not allowing you to do some things, like reusing a security context, so the security is baked into the scheme.
You still have to solve the key distribution problem, though. That's a thorny problem, and we don't have a good, scalable solution.
And now you see why algorithm agility is important, and why you want that OID sent as part of the key during the handshake phase :)

Play Framework 2.3 WS SSL Disable AlgorithmChecker

I'm currently trying to use WS in Play 2.3 to interact with the Visa Direct Payments API but I am struggling as the sandbox key provided is RSA has a key size of 1024 and, from what I've read in the source code comments, is considered not safe so is disabled.
As this is just sandbox I would like to know if there is a way to disable this extra key checking, I have already tried ws.acceptAnyCertificate=true without any luck.
The errors I am recieving in the console are as follows:
[warn] p.a.l.w.s.ConfigSSLContextBuilder - validateKeyStore: Skipping certificate with weak key size in visasandboxcert: Certificate failed: cert = "CN=841edac8-d8cd-4593-b575-fdf3bbee5e67,OU=VMT,O=Visa,L=Foster City,ST=CA,C=US" failed on constraint RSA keySize < 2048, algorithm = RSA, keySize = 1024
[error] play - Cannot invoke the action, eventually got an error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
Can anyone give me any advice how I can get round this? Preferably without changing the Play source code and building from that.
First, you need to talk to Visa Direct Payments and file a bug report letting them know that a 1024 bit key is utterly unacceptable in this day and age.
Second, you need to set:
ws.ssl.disabledKeyAlgorithms="RSA keySize < 1024"
which will tell the Algorithms checker to ease up. See Certificate Validation for more details.
if you are using play 2.6.x, you can do it this way
play.ws {
ssl {
debug.handshake = true
disabledKeyAlgorithms =["RSA keySize < 1024"]
}
}

Extracting modulus and exponent from public key using Openssl and C++

So I'm currently studying how networking works. I've got a bunch of packets from wireshark which I have already copied in buffers(only the content, without header. Wireshark->Follow TPC Stream->C arrays). I can understand the protocol but in the 3rd packet it requires a key exchange. After some googling I found that I need RSA encryption. It sends me a public key + token. And I shoud return encrypted shared key(just generated) and encrypted token which I received earlier.
RSA_key needs exponent and modulus, So my question is: How can I create RSA_key object from single char[] buffer(the public key).
NOTE:I'm posting here after long time googling. I may not be using the right keywords because I'm not english speaker. I could find threads asking this with php only.
The most useful (I think) link I found is http://www.techper.net/2012/06/01/converting-rsa-public-key-modulus-and-exponent-into-pem-file/
Thanks.
P.S. I'm sniffing minecraft and simulating client side(I choosed it because its popular game and I knew I will find resources on the web if I get stuck). However my question is exacly how to get modulus and exponent from a public key with format: http://pastebin.com/J9ddhgW5 (thats the bytes representing the public key)
Ohh I forgot, first column is the byte position, second column is the byte value typecasted to int, 3th column is again value but (int)(unsigned char) so I can see if its +127, 4th colums is the hex representation of the value and the last column is character based on ascii table(if its visible character).
The data you posted is an ASN.1 encoded (DER) RSA public key:
$ openssl ssl rsa -inform der -pubin -text < 12120862.key
Public-Key: (1024 bit)
Modulus:
00:81:1f:1d:00:7e:d0:c7:e2:2f:31:3d:0d:f0:a8:
ab:c1:ea:66:ba:af:1d:a4:eb:b3:fd:51:58:1c:1d:
81:ae:f0:99:9e:5c:26:67:b5:41:14:28:79:c0:29:
e5:56:96:06:b7:4b:a0:c9:7f:41:46:9a:7e:85:10:
a0:91:ea:58:bd:78:78:6d:3c:07:2a:3d:61:f3:ed:
42:8b:1e:dc:6d:2d:21:41:7a:e8:15:51:0d:75:84:
be:20:8c:76:43:8b:4b:67:6b:49:09:e9:20:a1:11:
53:a0:d9:30:b1:c2:27:a6:09:e1:56:36:ed:7e:9b:
23:e2:df:5b:bd:c5:66:ca:c5
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCBHx0AftDH4i8xPQ3wqKvB6ma6
rx2k67P9UVgcHYGu8JmeXCZntUEUKHnAKeVWlga3S6DJf0FGmn6FEKCR6li9eHht
PAcqPWHz7UKLHtxtLSFBeugVUQ11hL4gjHZDi0tna0kJ6SChEVOg2TCxwiemCeFW
Nu1+myPi31u9xWbKxQIDAQAB
-----END PUBLIC KEY-----
In OpenSSL, you can use the d2i_RSA_PUBKEY function to get a public key from an ASN.1-encoded file (like this one).