Erlang TLS with ED25519 certfile - erlang

I am creating server code using bare Erlang ssl:listen/2 function. I would like to use TLS certificate using ED25519 algorithm but the server is crashing upon handshake. By digging in the Erlang code it seems that this algorithm is not supported for TLS (it is crashing on this function: https://github.com/erlang/otp/blob/master/lib/public_key/src/pubkey_cert_records.erl#L109 ).
Is that correct or am I doing something wrong? Is there a way to enable the support for it? Some workaround?
For the reference this is how I generated my certificate:
openssl genpkey -algorithm ED25519 -out key.pem
openssl req -new -x509 -days 1825 -key key.pem -out cert.pem
And this is the crash data I am getting:
{
:function_clause,
[
{:pubkey_cert_records, :supportedPublicKeyAlgorithms, [{1, 3, 101, 112}], [file: 'pubkey_cert_records.erl', line: 109]},
{:pubkey_cert_records, :decode_supportedPublicKey, 1, [file: 'pubkey_cert_records.erl', line: 228]},
{:pubkey_cert_records, :decode_tbs, 1, [file: 'pubkey_cert_records.erl', line: 325]},
{:pubkey_cert_records, :decode_cert, 1, [file: 'pubkey_cert_records.erl', line: 42]},
{:public_key, :pkix_decode_cert, 2, [file: 'public_key.erl', line: 380]},
{:ssl_handshake, :get_cert_params, 1, [file: 'ssl_handshake.erl', line: 1613]},
{:tls_handshake_1_3, :get_certificate_params, 1, [file: 'tls_handshake_1_3.erl', line: 2245]},
{:tls_handshake_1_3, :do_start, 2, [file: 'tls_handshake_1_3.erl', line: 638]}
]
}
And also my code works perfectly fine with RSA certificate.
Thanks for any help

Seems like it is really not supported for OTP 23 and below.
It is planned to be included in OTP 24.0 release. See GitHub issue https://github.com/erlang/otp/issues/4637

Related

Getting Self Signed Cert to work with Home Assistant in Docker

I am running HA in a docker container. I have created a wildcard self-signed cert that I use elsewhere within my homelab. But I cannot get it to work within HA. Here is how I created my cert using openSSL
Create CA - Root Key
openssl genrsa -aes256 -out ca-key.pem 4096
Create Request
openssl req -new -x509 -sha256 -days 3650 -key ca-key.pem -out ca.pem
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:OH
Locality Name (eg, city) []:Cortland
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Real World Developers
Organizational Unit Name (eg, section) []:Internal
Common Name (e.g. server FQDN or YOUR name) []:RWD.com
Email Address []:realworlddevs#outlook.com
Create Server Cert Signing Request
create key
openssl genrsa -out cert-key.pem 4096
create request
openssl req -new -sha256 -subj "/CN=RealWorldDevelopers" -key cert-key.pem -out cert.csr (subject=anything)
create config
echo "subjectAltName=DNS:*.RWD.com,IP:192.168.50.10" >> extfile.cnf (powershell will at BOM - need to open with notepad++ and set to UTF8)
create cert
openssl x509 -req -sha256 -days 3650 -in cert.csr -CA ca.pem -CAkey ca-key.pem -out cert.pem -extfile extfile.cnf -CAcreateserial
I am also running Pi-Hole as my local DNS. Without the cert, my DNS routes to ha.rwd.com within my homelab just fine.
My configuration.yaml file contain the http node like so
# TLS Certs
http:
ssl_certificate: /config/fullchain.pem
ssl_key: /config/cert-key.pem
Spacing in the config is correct. The certs are in the config folder within the container.
Yet in my logs, i still get this:
2022-09-12 18:55:41.931 ERROR (MainThread) [homeassistant.setup] Error during setup of component http
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/http/init.py", line 355, in _create_ssl_context
context.load_cert_chain(self.ssl_certificate, self.ssl_key)
ssl.SSLError: [SSL] PEM lib (_ssl.c:3874)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/setup.py", line 235, in _async_setup_component
result = await task
File "/usr/src/homeassistant/homeassistant/components/http/init.py", line 180, in async_setup
await server.async_initialize(
File "/usr/src/homeassistant/homeassistant/components/http/init.py", line 272, in async_initialize
self.context = await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/src/homeassistant/homeassistant/components/http/init.py", line 358, in _create_ssl_context
raise HomeAssistantError(
homeassistant.exceptions.HomeAssistantError: Could not use SSL certificate from /config/fullchain.pem: [SSL] PEM lib (_ssl.c:3874)
2022-09-12 18:55:41.933 ERROR (MainThread) [homeassistant.setup] Unable to set up dependencies of api. Setup failed for dependencies: http
2022-09-12 18:55:41.935 ERROR (MainThread) [homeassistant.setup] Setup failed for api: (DependencyError(...), 'Could not setup dependencies: http')
2022-09-12 18:55:41.936 ERROR (MainThread) [homeassistant.setup] Unable to set up dependencies of auth. Setup failed for dependencies: http
2022-09-12 18:55:41.936 ERROR (MainThread) [homeassistant.setup] Setup failed for auth: (DependencyError(...), 'Could not setup dependencies: http')
Home Assistant in a docker container, so u must add the path of certs' directory to docker by adding mount:
Commandline arg:
--mount type=bind,source=/certdirectory,target=/config/ssl
Docker Compose:
volumes:
- type: bind
source: /certdirectory
target: /config/ssl
Or use Portainer GUI (must install)
Then modify the configuration.yaml:
http:
ssl_certificate: /config/ssl/fullchain.pem
ssl_key: /config/ssl/cert-key.pem

openssl key result too small?

I've got a docker that's perpetually in the RESTARTING status if an entrypoint.sh is run.
Checking docker logs, I see many repeats of these 2 chunks of error:
e is 65537 (0x010001)
140680312165760:error:28069065:UI routines:UI_set_result:result too small:../crypto/ui/ui_lib.c:765:You must type in 4 to 1023 characters
140680312165760:error:28069065:UI routines:UI_set_result:result too small:../crypto/ui/ui_lib.c:765:You must type in 4 to 1023 characters
140680312165760:error:0906906F:PEM routines:PEM_ASN1_write_bio:read key:../crypto/pem/pem_lib.c:330:
Generating RSA private key, 2048 bit long modulus
and
e is 65537 (0x010001)
unable to load Private Key
139751600240000:error:28069065:UI routines:UI_set_result:result too small:../crypto/ui/ui_lib.c:765:You must type in 4 to 1023 characters
139751600240000:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:536:
139751600240000:error:0906A065:PEM routines:PEM_do_header:bad decrypt:../crypto/pem/pem_lib.c:439:
Generating RSA private key, 2048 bit long modulus
My entrypoint.sh has this snippet regarding encryption:
openssl genrsa -des3 -passout pass:x -out /etc/apache2/ssl/pass.key 2048
openssl rsa -passin pass:x -in /etc/apache2/ssl/pass.key -out /etc/apache2/ssl/server.key
cat /tmp/ssl-info.txt | openssl req -new -key /etc/apache2/ssl/server.key -out /etc/apache2/ssl/server.csr
openssl x509 -req -days 365 -in /etc/apache2/ssl/server.csr -signkey /etc/apache2/ssl/server.key -out /etc/apache2/ssl/server.crt
This is a project I've taken over so I'm not fully familiar with this snippet, which is far more verbose than what I typically use to generate and use rsa keys, like in this possibly related thread.
Can anyone please shed some insight into how this error can be solved?
I believe it's an issue with pass:xin line 1, x being only 1 character long.
pass:gsahdg etc should work(gsahdg is a random string).

(Erlang) Got error while parsing ecsda public key pem file

I made private and public keys files as
openssl ecparam -name secp256k1 -genkey -out gen.pem
openssl ec -in gen.pem -pubout -out gen.pub
then I checked .pub file
openssl pkey -in gen.pub -pubin -text -noout
Public-Key: (256 bit)
pub:
04:fc:de:4f:2a:77:bd:c4:f2:74:2b:ba:b5:fc:85:
e4:aa:96:a7:8e:86:14:bc:0d:fa:8e:d2:dd:50:3c:
5d:fa:f4:07:f4:17:80:49:06:19:0c:72:03:63:4e:
07:37:e9:10:64:c8:33:a4:a3:7e:26:d8:df:79:21:
d7:2d:a6:01:80
ASN1 OID: secp256k1
After that start erl
erl
Erlang/OTP 18 [erts-7.2] [source-e6dd627] [64-bit] [smp:3:3] [async-threads:10] [hipe] [kernel-poll:false]
After execution of commands
1>rr(public_key),
{ok,RawData} = file:read_file("gen.pub"),
Decoded = public_key:pem_decode(RawData),
[public_key:pem_entry_decode(X) || X <- Decoded ].
I got exception
** exception error: no match of right hand side value
{error,{asn1,{invalid_length,1}}}
in function public_key:der_decode/2 (public_key.erl, line 229)
I know that there are workarounds, but I'm wondering if I do something wrong or there are errors in public key modules ?
UPD 1.
When we look at result
{ok,#'SubjectPublicKeyInfo'{algorithm = #'AlgorithmIdentifier'{algorithm = {1,2,840,10045,2,1},
parameters = <<6,5,43,129,4,0,10>>},
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>}}
we can see next :
{1,2,840,10045,2,1} is oid of ecPublicKey http://oid-info.com/get/1.2.840.10045.2.1
parameters = <<6,5,43,129,4,0,10>>
'OTP-PUB-KEY':decode('EcpkParameters',<<6,5,43,129,4,0,10>>).
gives us
{ok,{namedCurve,{1,3,132,0,10}}}
and
pubkey_cert_records:namedCurves({1,3,132,0,10}).
gives us our source curve - secp256k1, and
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>
is public key itself. But this is workaround how I said before.
I tried your steps and it worked for me straight away:
g#crayon2:~/test % openssl ecparam -name secp256k1 -genkey -out gen.pem
g#crayon2:~/test % openssl ec -in gen.pem -pubout -out gen.pub
read EC key
writing EC key
g#crayon2:~/test % openssl pkey -in gen.pub -pubin -text -noout
Public-Key: (256 bit)
pub:
04:f1:c8:13:a8:19:19:51:2b:d8:59:c9:25:3e:42:
27:a6:e7:a1:62:df:85:77:0c:ef:f7:0e:0e:19:93:
df:e6:f5:42:66:7e:ee:02:07:76:85:19:a4:a8:2d:
03:11:73:0c:b2:d4:4c:c7:0e:42:d3:30:b5:51:e3:
97:45:f8:b5:6a
ASN1 OID: secp256k1
g#crayon2:~/test % erl
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.2.1 (abort with ^G)
1> rr(public_key).
['AAControls','ACClearAttrs','AccessDescription',
'Algorithm','AlgorithmIdentifier',
'AlgorithmIdentifierPKCS-10','AlgorithmIdentifierPKCS-8',
'AlgorithmIdentifierPKCS5v2-0','AlgorithmIdentifierPKSC-7',
'AlgorithmNull','AnotherName','AttCertValidityPeriod',
'Attribute','AttributeCertificate',
'AttributeCertificateInfo','AttributePKCS-10',
'AttributePKCS-7','AttributeTypeAndValue',
'Attributes_SETOF',
'Attributes_SETOF_valuesWithContext_SETOF',
'AuthorityKeyIdentifier','BasicConstraints',
'BuiltInDomainDefinedAttribute','BuiltInStandardAttributes',
'Certificate','CertificateList','CertificationRequest',
'CertificationRequestInfo',
'CertificationRequestInfo_attributes_SETOF'|...]
2> {ok,Data}=file:read_file("gen.pub").
{ok,<<"-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE8cgTqBkZUSvYWcklPkInpuehYt+Fdwzv\n9w4OGZPf5vVCZn7u"...>>}
3> Dec=public_key:pem_decode(Data).
[#'SubjectPublicKeyInfo'{algorithm = <<48,86,48,16,6,7,42,
134,72,206,61,2,1,
6,5,43,129,4,0,10,
3,66,0,4,241,200,
...>>,
subjectPublicKey = not_encrypted}]
My OpenSSL version:
g#crayon2:~/test % openssl version
OpenSSL 1.0.1p-freebsd 9 Jul 2015
System is FreeBSD 10.2-RELEASE. Erlang version is in the shell output above. The gen.pub key that it generated for me (if you want to try to load it) is:
g#crayon2:~/test % cat gen.pub
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE8cgTqBkZUSvYWcklPkInpuehYt+Fdwzv
9w4OGZPf5vVCZn7uAgd2hRmkqC0DEXMMstRMxw5C0zC1UeOXRfi1ag==
-----END PUBLIC KEY-----
Do you maybe want to paste your key so that I can try to load it?
Edit:
Sorry, I missed the last step. This seems to be a bug in the OTP code. The der_decode/2 function is called with KeyType set to ECPoint, see the pem_entry_decode/1 function. But der_decode/2 expects Asn1Type. Calling the 'OTP-PUB-KEY' module directly seems to be working:
8> Bin = hd(Dec)#'SubjectPublicKeyInfo'.algorithm.
32> 'OTP-PUB-KEY':decode('SubjectPublicKeyInfo', Bin).
{ok,#'SubjectPublicKeyInfo'{algorithm = #'AlgorithmIdentifier'{algorithm = {1,
2,840,10045,2,1},
parameters = <<6,5,43,129,4,0,10>>},
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>}}
However I am not sure if it returns anything sensible. Maybe worth raising a bug in OTP with the code that you posted in this question as steps to reproduce. Then at least someone competent would verify why it doesn't work. I am sure the steps you followed are fine and the types returned and passed to further functions are OK as far as the documentation is concerned.
I found that lines in public_key.erl ( lines 136-137 )
'ECPoint' ->
der_decode(KeyType, Key0)
have to be replaced with
'ECPoint' ->
{{KeyType,Key0},der_decode('EcpkParameters', Params)}

AFNetworking 2.2 SSL pinning with self-signed certificate

I want to prevent my app/server communication from a MITM attack so I am trying to setup SSL pinning, but I am having problems getting it working with AFNetworking 2.2, using a self-signed certificate. I think it's mostly a problem with how I am generating the certificate.
I first tried generating a self-signed certificate according to these instructions:
Generating the private key:
sudo openssl genrsa -des3 -out server.key 2048
Generating the Signing Request, and using the domain name when asked for the Common Name:
sudo openssl req -new -key server.key -out server.csr
Generating the certificate:
sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Finally, converting it to der format (since AFNetworking requires it)
sudo openssl x509 -outform der -in server.crt -out server.der
The server is Ubuntu 12.04, running ngninx+passenger to serve up a Rails 4 app. Here is the bit of my nginx server config to turn on SSL:
server {
listen 80;
listen 443;
server_name myapp.com;
passenger_enabled on;
root /var/www/myapp/current/public;
rails_env production;
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
}
After restarting nginx, downloading the der file, adding it to my project, and renaming it "server.cer" (since AFNetworking requires the certificate to use the .cer extension), I use this code to turn on SSL pinning for my AFHTTPSessionManager subclass:
client.securityPolicy = [AFSecurityPolicy
policyWithPinningMode:AFSSLPinningModeCertificate];
Then, with the first request to the server AFNetworking attempts to verify that the "trust is valid in the AFServerTrustIsValid function:
static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
SecTrustResultType result = 0;
OSStatus status = SecTrustEvaluate(serverTrust, &result);
NSCAssert(status == errSecSuccess, #"SecTrustEvaluate error: %ld", (long int)status);
return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
}
If I put a breakpoint at the return, I can see that the result is always kSecTrustResultRecoverableTrustFailure.
If I skip the AFServerTrustIsValid function by setting allowInvalidCertificates to YES on the security policy, then the request succeeds. But I don't really want to allow invalid certificates if I don't have to.
Back to the drawing board, this SO question lead me to this tutorial on creating a self-signed cert with also creating a CA. I setup my openssl.cnf file like so:
[ req ]
default_md = sha1
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = United Kingdon
countryName_default = UK
countryName_min = 2
countryName_max = 2
localityName = Locality
localityName_default = London
organizationName = Organization
organizationName_default = Eric Organization
commonName = Common Name
commonName_max = 64
[ certauth ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:true
crlDistributionPoints = #crl
[ server ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
nsCertType = server
subjectAltName = DNS:myapp.com
crlDistributionPoints = #crl
[ crl ]
URI=http://testca.local/ca.crl
And then used these commands to generate everything. First the CA stuff:
sudo openssl req -config ./openssl.cnf -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer
Then again the server's private key:
sudo openssl genrsa -out server.key 2048
The signing request:
sudo openssl req -config ./openssl.cnf -new -key server.key -out server.req
The certificate:
sudo openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extfile openssl.cnf -extensions server -days 365 -outform PEM -out server.cer
And finally the der file:
sudo openssl x509 -outform der -in server.cer -out stopcastapp.com.der
When I update and restart nginx,, download and add the server.der to my project (making sure to rename it to server.cer and to reset the Simulator), I get the same exact result.
The dreaded kSecTrustResultRecoverableTrustFailure rears its ugly head again.
What am I doing wrong? Am I like WAY off on how this all works, or do I need to tweak just one little thing to get it all working? If you could help in any way I would really, really appreciate it (I've been on this problem for two days now). Thanks!
Somewhere in your code you need to specify this, or something similar. You need to tell the code to accept invalid certificates (AKA self signed).
self.allowsInvalidSSLCertificate = YES;

Creating p12 iOS developer certificate on Windows - error in last step

So, I've been looking around a lot of how to create a p12 file for iPhone development, and I think I'm doing exactly as I am supposed to, but at the last step I get some errors that are more or less impossible to decipher.
I am running Windows 7, and these are the steps I do:
1) Create the private key. I do this by running this command (cmd is opened in Administrator mode):
openssl genrsa -out mykey.key 2048
2) Create the CSR file
openssl req -new -key mykey.key -out developer_identify.csr
3) Upload the csr file to the iPhone dev site. Here I do the following:
Click on menu Identifiers --> App IDs, select the correct App ID, click Edit, click Create Certificate, click Continue, select the CSR-file created above and proceed. Wait for the site to tell me its all OK, and then download the *aps_development.cer* file.
4) Create the PEM file:
openssl x509 -in aps_development.cer -inform DER -out
developer_identity.pem -outform PEM
5) And lastly, create the p12 file (and this is where it fails):
openssl pkcs12 -export -inkey mykey.key -in developer_identity.pem
-out iphone_dev.p12
The output after the last command:
Loading 'screen' into random state - done
Enter Export Password:
Verifying - Enter Export Password:
8216:error:060740A0:lib(6):func(116):reason(160):NA:0:
8216:error:23077073:lib(35):func(119):reason(115):NA:0:
8216:error:2306C067:lib(35):func(108):reason(103):NA:0:
8216:error:23073067:lib(35):func(115):reason(103):NA:0:
The p12 file is 0 bytes.
The PEM file looks alright, starts with
-----BEGIN CERTIFICATE-----
then a lot of jibberish and then ends with
-----END CERTIFICATE-----

Resources