I am using OpenSSL to get the byte array of CRL (certificateRevocationList) with a specific dn from my local ldap server.
The CRL data is an ASN1 byte array as follows:
<308202bb 308201a3 02010130 0d06092a 864886f7 ... d179fa>
My intention is to validate a X509 certificate against the CRL.
I think I can use X509_CRL_get0_by_cert() to verify a certificate
https://www.openssl.org/docs/man1.1.0/crypto/X509_CRL_get0_by_cert.html
But first I need to create a X509_CRL structure from the byte array.
After that I need to verify my certificate against the X509_CRL.
Please help me to find a way.
You need to create BIO first. After that use d2i_X509_CRL_bio to create crl.
Appoximatelly like this:
BIO* memoryBIO = BIO_new_mem_buf(buffer, bufferSize);
X509_CRL* crl = d2i_X509_CRL_bio(memoryBIO, NULL);
Related
I am trying to connect to the HiveMQ broker using ESP32, a SIM7020 NB-IoT module and the library Magellan_SIM7020E found at:https://github.com/AIS-DeviceInnovation/Magellan_SIM7020E.
It requires an SSL certificate to be pasted in a header file with this format (here abbreviated), where the lines of XXXXXX are to be replaced with the characters of the certificate:
/= Certificate Authority info =/
/= CA Cert in PEM format =/
const char rootCA[] = {"-----BEGIN CERTIFICATE-----"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
...
...
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"-----END CERTIFICATE-----"};
const char clientCA[] = {"-----BEGIN CERTIFICATE-----"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
...
...
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXXXXXX"
"-----END CERTIFICATE-----"};
const char clientPrivateKey[] = {"-----BEGIN RSA PRIVATE KEY-----"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
...
...
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"-----END RSA PRIVATE KEY-----"};
I managed to work with the free service with this setup (using the non SSL client in the library) but the I am failing with the SSL version used to access the paid broker.
By free service I mean broker.hivemq.com and by paid I mean xxxxxxx.s2.eu.hivemq.cloud.
I tried to use the certificate indicated in the FAQ (https://community.hivemq.com/t/frequently-asked-questions/514) which gives me a file called isrgrootx1.pem but it has a different format.
I tried cutting the .pem into sections with length that match each of the three entries required in the header file but the total length does not match.
The downloaded .pem file has a single block of 1856 characters whereas the ESP32 seems to need three blocks for root, client and client private with lengths of 1116, 1232 and 1592 respectively, adding up to much more than the PEM file length.
Is this the right file?
If so, how do I convert it to the format that I need?
If not, where from can I get the certificate?
I tried to follow a previous answer (Can't connect ESP32 to MQTT). That is for WiFi, not NB-IoT but it seems to require a similar format for the certificate. It is suggeseted to install and use OpenSSL but I can't figure out how to install it and I don't even know if it would actually do what I need if I did manage to install it.
As an alternative is there any way I can access the paid broker without SSL as I don't really need that level of security and it is an added complication, especially with regard to keeping the certificates up to date.
In Apple's documentation for the keys available for a Wallet pass, there's an option for a dictionary for NFC-related data. I understand that use of this key requires special permission from Apple. Regardless ...
message is straight forward -- it's the data passed to a NFC terminal (usually a unique identifier for the customer).
encryptionPublicKey, however, has me confused. Apple states it is the public encryption key used by the Value Added Services protocol. Use a Base64 encoded X.509 SubjectPublicKeyInfo structure containing a ECDH public key for group P256.
Can anyone explain what this second sentence means and/or what a developer would have to do to generate this? From what would one even generate the public/private keys?
You'll need the following to generate the public and private key. The private key is used by the merchant hardware when reading the pass and decoding the payload.
The compressed public key is what goes into your pass.json.
openssl ecparam -name prime256v1 -genkey -noout -out nfcKey.pem
openssl ec -in nfcKey.pem -pubout -out nfcPubkey.pem -conv_form compressed
cat nfcPubkey.pem
Outputs:
-----BEGIN PUBLIC KEY-----
MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/Bu9nyAtG1DQe7t7jszLb+dZ1GbX
oR8G0rIXoak67NM=
-----END PUBLIC KEY---
You'll need Base64 key (without the newline) for the encryptionPublicKey field.
E.g.
MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/Bu9nyAtG1DQe7t7jszLb+dZ1GbXoR8G0rIXoak67NM=
I am working on a project that needs to read a RSA private key (DER format) into a MacOS's SecKeyRef object.
I generate the key by
openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -outform DER -out private.der
I load the private.der to MacOS by using SecKeyCreateWithData:
unsigned char *keyBytes; // contains all the bytes from the file "private.der"
int keyBytesLen; // length of the data loaded
NSData keyData = [NSData dataWithBytes:keyBytes length:keyBytesLen];
NSDictionary* options = #{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA,
(id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
(id)kSecAttrKeySizeInBits: #1024};
SecKeyRef privateKey = SecKeyCrecateWithData((__bridge CFDataRef) keyData, (__bridge CFDictionaryRef) options, &error);
OSstatus status = SecKeyDecrypt(privateKey, .... some encrypted message);
// status returns -50 (errSecParam)
So I notice the privateKey is loaded successfully, but it fails to decrypt the encrypted message. I am 100% sure other parameters I have put into SecKeyDecrypt() function is correct because it works if I generate the privateKey by macOS's built-in function rather than loading from a DER-format file generated by openssl.
I also notice that when I dump the key (binary format), the first few bytes (version header) is different from the key generated by MacOS's built-in function and openssl. If the key is generated by MacOS (ex: SecKeyGeneratePair) and outputed by SecKeyCopyExternalRepresentation, the first few bytes look like:
3082 025d 0201 0002 8181 ...
while the key generated by openssl looks like:
3082 025c 0201 0002 8181 ...
I know (based on PKCS#1) that these bytes represent the "version" of the private key but not sure how to interpret it.
Any help or similar working example to load key generated by openssl to MacOS's API will be appreciated
I am creating a CSR using this library on iOS and then encoding it as Base 64.
https://github.com/ateska/ios-csr
The library creates the CSR as NS Data on iOS.
I am able to send this data to my Node.JS server. I want to convert this to a PEM so that I can sign this CSR using the server's private key. Does anyone know how to do this?
Thanks
With SCCCSR from ios-csr library you will have a certificate request in PKCS#10 format, encoded in binary
let certificateRequest = sccsr.build(publicKey, privateKey: privateKey)
A PEM format requires a conversion to Base64 and around with the -----BEGIN CERTIFICATE REQUEST----- and -----END CERTIFICATE REQUEST----- headers
let certificateRequestB64 = certificateRequest.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
let certificateRequestPEM =
"-----BEGIN CERTIFICATE REQUEST-----\\n" + certificateRequestB64 + "\\n-----END CERTIFICATE REQUEST-----\\n"
I keep seeing disjointed accounts all over the web of what the .cer file is and how to generate it so that the app can properly communicate with the server via https.
To quote this source, one person says:
1) You now need .cer files in your bundle for all certificates in the chain. So, at least, two certificate files must be present (your certificate and the root CA). In our case, we needed an intermediate as well.
2) These certificates must be in a particular order. Specifically, the certificate that certifies the host that you are communicating with must be first in the list of pinned certificates/keys. It doesn't look like the order of the rest of them matter. This is because AFSecurityPolicy uses the first object in the array to validate the host name.
3) The host validation fails for wildcard certificates if you are communicating with the root domain. For example, consider a certificate pointed at *.foo.com. If you are communicating with foo.com, the host check will fail because the host component counts will not match. I understand the need for this early optimization, but it fails before it even reaches the logic that specifically handles wildcard domains.
Official documentation backs that up here.
I suppose that in order to generate this, one must cat the contents of their whole cert chain into a .cer file in a specific order. I remember seeing this posted somewhere, but can't seem to find it.
The question is, what is the undebatable method of creating a .cer file for AFNetworking?
UPDATE:
After more research, it seems to me that you simply take the .crt file and perform this on it:
openssl x509 -in www.mydomain.com.crt -out www.mydomain.com.cer -outform der
However, even after doing this and attaching the .cer to my app bundle, I get an error here:
+ (NSArray *)pinnedPublicKeys {
static NSArray *_pinnedPublicKeys = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSArray *pinnedCertificates = [self pinnedCertificates];
NSMutableArray *publicKeys = [NSMutableArray arrayWithCapacity:[pinnedCertificates count]];
for (NSData *data in pinnedCertificates) {
SecCertificateRef allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data);
NSParameterAssert(allowedCertificate);
The error comes in at the last line. I suppose that in the preceding line where it attempts to assign an allowedCertificate, SecCertificateCreateWithData has the following description:
/*!
#function SecCertificateCreateWithData
#abstract Create a certificate given it's DER representation as a CFData.
#param allocator CFAllocator to allocate the certificate with.
#param certificate DER encoded X.509 certificate.
#result Return NULL if the passed-in data is not a valid DER-encoded
X.509 certificate, return a SecCertificateRef otherwise.
*/
Clearly it is returning a NULL, but I don't know why. My specific certificate is in the correct format. However, I did notice that there were other 'certificates' in the pinnedCertificates array, but I have no idea where it is getting them. Nor can I seem to find them or print them out. As far as I know, I only have the one in the app bundle, but it seems to show more than that.
The error generated from the assert on the last line is:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: allowedCertificate'
Assuming you are using AFNetworking 2.5 the steps described below:
Install valid certificate on your server
Create .cer file openssl x509 -in www_yourdomain_com.crt -out www_yourdomain_com.cer -outform der
Add .cer file to app project. IMPORTANT: Never add private key to your project!!!
Setup AFNetworking secure policy
- (AFSecurityPolicy *)securityPolicy {
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setAllowInvalidCertificates:NO];
[securityPolicy setValidatesDomainName:YES];
return securityPolicy;
}
Set policy on network manager when making network call
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager setSecurityPolicy:[self securityPolicy]];
There's no need to manually load .cer file, if you're using policyWithPinningMode:pinningMode method to create security policy AFNetworking automatically pins them.