"x509: certificate signed by unknown authority" when running kubelet - kubernetes

I'm trying to install kubernetes with kubelet 1.4.5 on CoreOS beta (1192.2.0).
I'm using a slightly modified version of the controller and worker install scripts from https://github.com/coreos/coreos-kubernetes/tree/master/multi-node/generic
so in general I created the licenses on Gentoo Linux using the following bash script:
#!/bin/bash
export MASTER_HOST=coreos-2.tux-in.com
export K8S_SERVICE_IP=10.3.0.1
export WORKER_IP=10.79.218.3
export WORKER_FQDN=coreos-3.tux-in.com
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"
openssl genrsa -out apiserver-key.pem 2048
openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config openssl.cnf
openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile openssl.cnf
openssl genrsa -out ${WORKER_FQDN}-worker-key.pem 2048
openssl req -new -key ${WORKER_FQDN}-worker-key.pem -out ${WORKER_FQDN}-worker.csr -subj "/CN=${WORKER_FQDN}" -config worker-openssl.cnf
openssl x509 -req -in ${WORKER_FQDN}-worker.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out ${WORKER_FQDN}-worker.pem -days 365 -extensions v3_req -extfile worker-openssl.cnf
openssl genrsa -out admin-key.pem 2048
openssl req -new -key admin-key.pem -out admin.csr -subj "/CN=kube-admin"
openssl x509 -req -in admin.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out admin.pem -days 365
echo done
and this is openssl.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = #alt_names
[alt_names]
DNS.1 = coreos-2.tux-in.com
DNS.2 = coreos-3.tux-in.com
IP.1 = 10.3.0.1
IP.2 = 10.79.218.2
IP.3 = 10.79.218.3
and this is my worker-openssl.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = #alt_names
[alt_names]
IP.1 = 10.79.218.3
DNS.1 = coreos-3.tux-in.com
My controller machine is coreos-2.tux-in.com which resolves to the lan ip 10.79.218.2
my worker machine is coreos-3.tux-in.com which resolves to lan ip 10.79.218.3
it created the licenses just fine. but when I use them and install the controller script on the main machine, i see that when I run journalctl -xef -u kubelet and I noticed the following messages:
Nov 08 21:24:06 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:06.805868 2018 event.go:208] Unable to write event: 'x509: certificate signed by unknown authority' (may retry after sleeping)
Nov 08 21:24:06 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:06.950827 2018 reflector.go:203] pkg/kubelet/kubelet.go:384: Failed to list *api.Service: Get https://coreos-2.tux-in.com:443/api/v1/services?resourceVersion=0: x509: certificate signed by unknown authority
Nov 08 21:24:07 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:07.461042 2018 reflector.go:203] pkg/kubelet/config/apiserver.go:43: Failed to list *api.Pod: Get https://coreos-2.tux-in.com:443/api/v1/pods?fieldSelector=spec.nodeName%3D10.79.218.2&resourceVersion=0: x509: certificate signed by unknown authority
Nov 08 21:24:07 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:07.461340 2018 reflector.go:203] pkg/kubelet/kubelet.go:403: Failed to list *api.Node: Get https://coreos-2.tux-in.com:443/api/v1/nodes?fieldSelector=metadata.name%3D10.79.218.2&resourceVersion=0: x509: certificate signed by unknown authority
Nov 08 21:24:08 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:08.024366 2018 reflector.go:203] pkg/kubelet/kubelet.go:384: Failed to list *api.Service: Get https://coreos-2.tux-in.com:443/api/v1/services?resourceVersion=0: x509: certificate signed by unknown authority
Nov 08 21:24:08 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:08.171170 2018 eviction_manager.go:162] eviction manager: unexpected err: failed GetNode: node '10.79.218.2' not found
Nov 08 21:24:08 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:08.543619 2018 reflector.go:203] pkg/kubelet/kubelet.go:403: Failed to list *api.Node: Get https://coreos-2.tux-in.com:443/api/v1/nodes?fieldSelector=metadata.name%3D10.79.218.2&resourceVersion=0: x509: certificate signed by unknown authority
Nov 08 21:24:08 coreos-2.tux-in.com kubelet-wrapper[2018]: E1108 21:24:08.543926 2018 reflector.go:203] pkg/kubelet/config/apiserver.go:43: Failed to list *api.Pod: Get https://coreos-2.tux-in.com:443/api/v1/pods?fieldSelector=spec.nodeName%3D10.79.218.2&resourceVersion=0: x509: certificate signed by unknown authority

The kubelet documentation says that the --tls-cert-file flag needs the CA be concatenated after the certificate. In you case it is the apiserver.pem:
--tls-cert-file File containing x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert). If --tls-cert-file and --tls-private-key-file are not provided, a self-signed certificate and key are generated for the public address and saved to the directory passed to --cert-dir.
If I read you certificate generation correctly, the apiserver.pem doesn't contain the root ca.

0. if your issue is :
: Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "x509: invalid signature: parent certificate cannot sign this kind of certificate"
1. look at your ca.crt
openssl x509 -noout -text -in ca.crt, you will find below info :
X509v3 Basic Constraints:
CA:FLASE
X509v3 Basic Constraints means :
"Basic Constraints" identifies if the subject of certificates is a CA who is allowed to issue child certificates. For a certificate that can be used to sign certificates, the info is in some sense duplicated: X509v3 Basic Constraints: CA: TRUE --- Can sign certificates.
you should modify it to CA:TRUE through vi openssl.conf
[ v3_ca ]
basicConstraints = CA:true
Regenerate your crts.

I'm using kubelet with rkt on CoreOS 1192.2.0.
This is the unit i use to start kubelet on the worker:
[Unit]
Description=Kubelet via Hyperkube ACI
Requires=k8s-assets.target
After=k8s-assets.target
[Service]
EnvironmentFile=/etc/proxy.env
Environment="RKT_OPTS=--volume=resolv,kind=host,source=/etc/resolv.conf --mount volume=resolv,target=/etc/resolv.conf --volume var-log,kind=host,source=/var/log --mount volume=var-log,target=/var/log"
Environment=KUBELET_VERSION=v1.4.0_coreos.0
ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
ExecStart=/usr/lib/coreos/kubelet-wrapper \
--api-servers=https://10.203.69.108 \
--register-node=true \
--allow-privileged=true \
--config=/etc/kubernetes/manifests \
--hostname-override=node2.my.domain \
--cluster_dns=10.3.0.10 \
--cluster_domain=cluster.local \
--kubeconfig=/etc/kubernetes/worker-kubeconfig.yaml \
--tls-cert-file=/etc/kubernetes/ssl/worker.pem \
--tls-private-key-file=/etc/kubernetes/ssl/worker-key.pem
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
What is important is
--api-servers that must point to the IP address of the master
--tls-cert-file that must point to the worker certificate public key
--tls-private-key-file that must point to the worker certificate private key
--kubeconfig that must point to a valid kubeconfig file
Here my kubeconfig file (it contain the path to the CA that have signed the certificates):
apiVersion: v1
kind: Config
clusters:
- name: local
cluster:
certificate-authority: /etc/kubernetes/ssl/ca.pem
users:
- name: kubelet
user:
client-certificate: /etc/kubernetes/ssl/worker.pem
client-key: /etc/kubernetes/ssl/worker-key.pem
contexts:
- context:
cluster: local
user: kubelet
name: kubelet-context
current-context: kubelet-context

Your OpenSSL certificates are "self-signed":
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"
That is to say, you are signing them instead of a trusted certificate authority. It should be completely fine and safe, as long as you keep the private keys safe.
If you want it to be signed by a certificate authority, you will need to generate a CSR (certificate signing request).
https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs

in general the solution was to create another etcd2 port that attaches to loopback device of each machine and works on http instead of https. more information at calico-policy-controller requests etcd2 certificates of a different coreos server

Related

Kafka won't start again

Dears,
I do not have any idea what is wrong in my configuration. When I want to start Kafka service I've got an error:
[2020-11-30 08:52:33,502] DEBUG Created SSL context with keystore SecurityStore(path=/etc/pki/CA/certs/node1.corp.jks, modificationTime=Mon Nov 30 08:40:08 CET 2020), truststore SecurityStore(path=/etc/pki/ca-trust/extracted/java/cacerts, modificationTime=Wed Nov 25 09:20:22 CET 2020), provider SunJSSE. (org.apache.kafka.common.security.ssl.SslEngineBuilder)
[2020-11-30 08:52:33,702] ERROR [KafkaServer id=1] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: org.apache.kafka.common.config.ConfigException: Invalid value javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target for configuration A client SSLEngine created with the provided settings can't connect to a server SSLEngine created with those settings.
at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:158)
at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:146)
at org.apache.kafka.common.network.ChannelBuilders.serverChannelBuilder(ChannelBuilders.java:85)
at kafka.network.Processor.<init>(SocketServer.scala:753)
at kafka.network.SocketServer.newProcessor(SocketServer.scala:394)
at kafka.network.SocketServer.$anonfun$addDataPlaneProcessors$1(SocketServer.scala:279)
at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:158)
at kafka.network.SocketServer.addDataPlaneProcessors(SocketServer.scala:278)
at kafka.network.SocketServer.$anonfun$createDataPlaneAcceptorsAndProcessors$1(SocketServer.scala:241)
at kafka.network.SocketServer.$anonfun$createDataPlaneAcceptorsAndProcessors$1$adapted(SocketServer.scala:238)
at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
at kafka.network.SocketServer.createDataPlaneAcceptorsAndProcessors(SocketServer.scala:238)
at kafka.network.SocketServer.startup(SocketServer.scala:121)
at kafka.server.KafkaServer.startup(KafkaServer.scala:263)
at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:44)
at kafka.Kafka$.main(Kafka.scala:84)
at kafka.Kafka.main(Kafka.scala)
Caused by: org.apache.kafka.common.config.ConfigException: Invalid value javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target for configuration A client SSLEngine created with the provided settings can't connect to a server SSLEngine created with those settings.
at org.apache.kafka.common.security.ssl.SslFactory.configure(SslFactory.java:100)
at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:154)
... 18 more
I've got three files from other Team: CAroot certificate (PEM *.crt), Private key (PEM private *.pem) and certificate (PEM *.crt) for each node.
The keystore was create like this:
keytool -noprompt -keystore node1.corp.jks -alias rootca -import -file testcorp.crt -storepass kafka123
Next key was imported to truststore and keystore like this:
openssl pkcs12 -export -in node1.crt -inkey node1.pem -out node1.p12 -password pass:kafka123
keytool -noprompt -importkeystore -srckeystore node1.p12 -srcstoretype PKCS12 -destkeystore node1.corp.jks -dname "CN=node1, OU=ITC, O=ITC, L=CITY, ST=SOME, C=PL" -deststoretype JKS -storepass kafka123 -keypass kafka123 -keyalg RSA -validity 365
Kafka configuration file looks like:
broker.id=1
delete.topic.enable=true
auto.create.topics.enable=true
listeners=SASL_SSL://:9093
advertised_listeners=SASL_SSL://192.168.1.101:9093
ssl.endpoint.identification.algorithm=
sasl.enabled.mechanisms=SCRAM-SHA-512
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512
security.inter.broker.protocol=SASL_SSL
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
allow.everyone.if.no.acl.found=true
ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1
ssl.secure.random.implementation=SHA1PRNG
super.users=User:admin
ssl.client.auth=none
ssl.keystore.location=/etc/pki/CA/certs/node1.corp.jks
ssl.keystore.password=kafka123
ssl.key.password=kafka123
ssl.truststore.location=/etc/pki/ca-trust/extracted/java/cacerts
ssl.truststore.password=kafka123
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
offsets.topic.replication.factor=3
transaction.state.log.replication.factor=3
transaction.state.log.min.isr=3
log.dirs=/kafka_data
num.partitions=1
num.recovery.threads.per.data.dir=1
log.flush.interval.messages=10000
log.flush.interval.ms=1000
log.retention.hours=168
log.retention.bytes=1073741824
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181
I do not have any idea what is wrong. Did you have similar problems? Do you have any idea what is wrong?
Best Regards,
Dan
Something changed in our DNS serwer. Recreation of keystores solved problems.

Setup Postgres SSL connection from wildfly

I'm trying to setup an SSL connection from wildfly to CloudSQL Postgres DB.
After having downloaded ssl certs from CloudSQL (server-ca.pem, client-cert.pem and client-key.pem), I created keystore and trustore in the following way:
keytool -import -alias server -file server-ca.pem -keystore truststore.jks -storepass password
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out client.p12 -name client
keytool -importkeystore -deststorepass password -destkeystore keystore.jks -srckeystore client.p12 -srcstoretype PKCS12 -srcstorepass password -alias client
Then I've changed JAVA_OPTS env variable, to provide the keystore created:
export JAVA_OPTS="-server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djavax.net.ssl.keyStore=keystore.jks -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=truststore.jks -Djavax.net.ssl.trustStorePassword=password"
Then I've changed postgres datasource in standalone.xml:
jdbc:postgresql://XX.XX.XX.XX:5432/db?sslmode=require
At wildfly startup, I got the following error:
org.postgresql.util.PSQLException: FATAL: connection requires a valid client certificate
Any idea?
Cloud SQL creates a server certificate automatically when you create your instance. As long as the server certificate is valid, the certificate has an expiration date; after that date, it is no longer valid, and clients are not able to establish a secure connection to your instance using that certificate.
https://cloud.google.com/sql/docs/postgres/configure-ssl-instance

When a server has multiple cerificates, which certificate has the public key?

I wanted to have the public key of a server. The team managing the server said to me that i can extract the certificates using openssl e.g. with command
openssl s_client -connect hostAddress.org:443 -showcerts
and this certificate will have the public key.
Using the above command, i get 3 certificates. The full output of the command is:
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root CA
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
0 s:/C=CZ/L=Praha/O=CESNET/CN=hostAddress
i:/C=NL/ST=Noord-Holland/L=Amsterdam/O=TERENA/CN=TERENA SSL CA 3
-----BEGIN CERTIFICATE-----
SOME TEXT
-----END CERTIFICATE-----
1 s:/C=NL/ST=Noord-Holland/L=Amsterdam/O=TERENA/CN=TERENA SSL CA 3
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA
-----BEGIN CERTIFICATE-----
SOME TEXT
-----END CERTIFICATE-----
2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA
-----BEGIN CERTIFICATE-----
SOME TEXT
-----END CERTIFICATE-------
Server certificate
subject=/C=CZ/L=Praha/O=CESNET/CN=hostAddress
issuer=/C=NL/ST=Noord-Holland/L=Amsterdam/O=TERENA/CN=TERENA SSL CA 3
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5097 bytes and written 489 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-SHA384
Session-ID: 5B9A6ACCEFE2608E33AEE1FAF8F3136A7C41D081416F885613A0C48A4D9556CD
Session-ID-ctx:
Master-Key: 83D7239981A232F1AB175F2F4980B1D6B7B1D4109878022A8FE8B3D2CD95F14D33AB2112E5F27CD1D508CE3D5EE34854
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1536846540
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
From these 3 certificates, how do i know which one has the public key for the host?
The certificate labelled 0 is the server certificate. The certificate labelled 1 is the certificate for the Certificate Authority (CA) which issued the server certificate, (and so on, ) up to the last one (the somewhat standard "2"), which is the root certificate where "oh, I trust this" was established.
So, you're looking for the first one.

How to get Outlook smtp certificate?

I am trying to get smtp certificate from outlook, so I can import it into my weblogic server but I have problems with getting the certificate.
For the imap certificate I didnĀ“t have any problem with getting the certificate.
In my linux terminal I use the next command.
openssl s_client -connect outlook.office365.com:993
openssl s_client -connect smtp.office365.com:587
The outlook port and server list
ESMTP uses a delayed-start TLS session (via the STARTTLS verb).
You need to add -starttls smtp to your command.
$ openssl s_client -connect smtp.office365.com:587 -starttls smtp
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Cloud Services CA-1
verify return:1
depth=0 C = US, ST = WASHINGTON, L = Redmond, O = Microsoft Corporation, CN = outlook.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=WASHINGTON/L=Redmond/O=Microsoft Corporation/CN=outlook.com
i:/C=US/O=DigiCert Inc/CN=DigiCert Cloud Services CA-1
1 s:/C=US/O=DigiCert Inc/CN=DigiCert Cloud Services CA-1
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGZTCCBU2gAwIBAgIQAwR02adRep0z9LQcAP1P5zANBgkqhkiG9w0BAQsFADBL
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSUwIwYDVQQDExxE
aWdpQ2VydCBDbG91ZCBTZXJ2aWNlcyBDQS0xMB4XDTE2MTIxMjAwMDAwMFoXDTE3
MTIxMjEyMDAwMFowajELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldBU0hJTkdUT04x
EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
bjEUMBIGA1UEAxMLb3V0bG9vay5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDH6/5crqaQKLccqDtM5kIsyksPsfsjeTkefQaRzSC9xvmUJS6osy6/
E5xohSvyaOBRu2PwafpP2ERoTEGOa4iKY8QDD8NoZiLmwbqC2s5sU26qcgo9zhGV
oQ4XRu/OFXaRfsHs6QQ4Q3GktnQFRlxNLmodle/DqCq1SFDKq+oPLkFvrAdv0LRQ
C817LzyN8/rRPvffCAgz7pcKXWPbJ0Nqodtnq3EjQSNYuTNSjYa5ehNZ2LqeGuF0
FrtS2Pli4zpFxgaLxOx0VNWWx5UmBA6I2FFoQsss3pHBLurS2mPJMomf1l2UD+AP
dY0OO0XSXL+7iDY4yx/av4SA1nr1Xz2tAgMBAAGjggMkMIIDIDAfBgNVHSMEGDAW
gBTdUdCiMXOpc66PtAF+XYxXy5/w9zAdBgNVHQ4EFgQUg6//TInu7Qp+2D4v7VX4
nJ+F3xYwggFDBgNVHREEggE6MIIBNoIdY2NzLmxvZ2luLm1pY3Jvc29mdG9ubGlu
ZS5jb22CIWNjcy1zZGYubG9naW4ubWljcm9zb2Z0b25saW5lLmNvbYILb3V0bG9v
ay5jb22CDSoub3V0bG9vay5jb22CDW9mZmljZTM2NS5jb22CDyoub2ZmaWNlMzY1
LmNvbYIKKi5saXZlLmNvbYIWKi5pbnRlcm5hbC5vdXRsb29rLmNvbYIXKi5vdXRs
b29rLm9mZmljZTM2NS5jb22CEm91dGxvb2sub2ZmaWNlLmNvbYIdYXR0YWNobWVu
dC5vdXRsb29rLm9mZmljZS5uZXSCIGF0dGFjaG1lbnQub3V0bG9vay5vZmZpY2Vw
cGUubmV0ghYqLmNsby5mb290cHJpbnRkbnMuY29tggwqLm9mZmljZS5jb20wDgYD
VR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCBjQYD
VR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl
cnRDbG91ZFNlcnZpY2VzQ0EtMS1nMS5jcmwwP6A9oDuGOWh0dHA6Ly9jcmw0LmRp
Z2ljZXJ0LmNvbS9EaWdpQ2VydENsb3VkU2VydmljZXNDQS0xLWcxLmNybDBMBgNV
HSAERTBDMDcGCWCGSAGG/WwBATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k
aWdpY2VydC5jb20vQ1BTMAgGBmeBDAECAjB8BggrBgEFBQcBAQRwMG4wJQYIKwYB
BQUHMAGGGWh0dHA6Ly9vY3NweC5kaWdpY2VydC5jb20wRQYIKwYBBQUHMAKGOWh0
dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydENsb3VkU2VydmljZXND
QS0xLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQB/rAdq8HgN
H6bxwklntH0f4CCuh4g/XmpemDYx4Ffcwo+eWboyOM2cPUT0YtkqTRx1OFYDF7FL
V3FIP0Gp/wLl+d7B/Y2aweXMzngAKrhT1/5CUAqDVQN2nERwFDi8bwrwGo6Y2ey3
gXtvIKox2vZR9XyTOit0z5AMsNHdJXLyUMotGMnJTiVxhKEOZzSFotvIfrYFldep
os4Hw8FjiHERvR23FUqaInM+9/Dz2rG0ikWdskUoboynm3iTPwczaHe7TYA30o7w
Uc+2QXkhHeUDL0TApOSgo++CILBEcOegpaiDlqkXBaRDNnTZyoQhl3vnJ/uVQ87l
emTkXreuX/Sd
-----END CERTIFICATE-----
subject=/C=US/ST=WASHINGTON/L=Redmond/O=Microsoft Corporation/CN=outlook.com
issuer=/C=US/O=DigiCert Inc/CN=DigiCert Cloud Services CA-1
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:ECDSA+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:DSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:ECDSA+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:DSA+SHA1
Peer signing digest: SHA1
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 3765 bytes and written 566 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-SHA384
...
---
250 SMTPUTF8
DONE

Import X509 certificate with subjectAltName (SAN) into JKS keystore

I'm using pyOpenSSL to create a X509 certifcate. I need to import this certificate into a Java JKS keystore to make it available to my Java application. This is working fine as long as I don't add a subjectAltName extension to the certificate. If the certificate has an alternative subject set, import into the JKS keystore fails:
root#51561a8a1e01:~# /opt/oracle/java/jdk64-1.8.0_92/bin/keytool -keystore keystore -storepass changeit -noprompt -importcert -alias example -file certificate.crt -v
keytool error: java.lang.Exception: Input not an X.509 certificate
java.lang.Exception: Input not an X.509 certificate
at sun.security.tools.keytool.Main.doCommands(Main.java:1009)655)
at sun.security.tools.keytool.Main.main(Main.java:336)
root#51561a8a1e01:~#
If I print this certificate using OpenSSL on the command line, I get this output:
root#51561a8a1e01:~# openssl x509 -in certificate.crt -text -noout
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 0 (0x0)
Signature Algorithm: sha256WithRSAEncryption
Issuer: OU=example.com, CN=my-server.example.com, O=example.com
Validity
Not Before: Aug 26 12:03:03 2016 GMT
Not After : Aug 25 12:03:03 2021 GMT
Subject: OU=example.com, CN=my-server.example.com, O=example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cc:a7:53:5a:38:...:11:2f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost
Signature Algorithm: sha256WithRSAEncryption
ab:51:12:fb:a6:a6:...:0d:4b
That is the certificate is obviously valid. And according to oracle's documentation the Java 8 keytool should support the SubjectAlternativeName extension.
When I tried to generate everything with keytool itself - which seems to work - I noticed that the certificate generated by keytool has a second extension X509v3 Subject Key Identifier:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1510484556 (0x5a082a4c)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=example.com, OU=example.com, CN=my-server.example.com
Validity
Not Before: Aug 26 12:52:43 2016 GMT
Not After : Nov 24 12:52:43 2016 GMT
Subject: O=example.com, OU=example.com, CN=my-server.example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:99:b6:b1:11:a6:...:7b:39
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost
X509v3 Subject Key Identifier:
66:75:AD:7A:A5:19:AB:43:DE:55:E4:A7:4F:C2:3D:53:55:49:CE:48
Signature Algorithm: sha256WithRSAEncryption
50:7c:fe:c8:5d:1b:...:da:27
Do I need to add this extension to my certificate using pyOpenSSL as well. But what would be the correct value?!
Well, just after writing down everything for this question I noticed that there is a second difference between the certificate generated with pyOpenSSL and the keytool one. The keytool certificate states Version: 3 (0x2) while the other one says Version: 1 (0x0).
I'm not too much into the X509 specs but as the extensions are all prefixed with X509v3 I'd guess that extension support is not available for version 1 certificates.
And after adapting my python code to set the version to 3 (actually 2 as version is 0 based), import into keytool works as expected:
_req = OpenSSL.crypto.X509Req()
_req.set_version(2)
...