AWS iot self signed certs script - aws-cli

I am attempting to create an automated version fo this process https://aws.amazon.com/premiumsupport/knowledge-center/iot-self-signed-certificates/
But i am running into some issues. I keep getting an error when I attempt to use the iot registration code for the CN field of the command
openssl req -new -key verificationCert.key -out verificationCert.csr -subj "/CN=$CN"
Im having trouble with appending the variable I have stored the registration code to into the CN portion.
When I do this manually it works.
--UPDATE--
openssl genrsa -out myRootCA.key 2048
openssl req -x509 -new -nodes -key myRootCA.key -sha256 -days 730 -subj "/C=US/ST=Massachusetts/L=Boston/O=Company/OU=USBDev/CN=CA STG CERT" -out myRootCA.pem
CN=$(aws iot get-registration-code | jq --raw-output .registrationCode)
openssl genrsa -out privateKeyCert.key 2048
openssl req -new -key privateKeyCert.key -subj "/CN=$CN" -out privateKeyCert.csr
openssl x509 -req -in privateKeyCert.csr -CA myRootCA.pem -CAkey myRootCA.key -CAcreateserial -out privateKeyCert.pem -days 730 -sha256
aws iot register-ca-certificate --ca-certificate file://myRootCA.pem --verification-cert file://privateKeyCert.pem

Step 1 : Generate the CA key and certificate
openssl genrsa -out cacert.key 2048
openssl req -x509 -new -nodes -key cacert.key -sha256 -days 365 -subj "C=US/ST=Massachusetts/L=Boston/O=Zoom Tel/OU=USBSensor iot/CN=CA STG CERT" -out cacert.pem
Step 2 : Getting registration code to put as the CN in a CSR
aws iot get-registration-code
{
"registrationCode": "xxxxxxx"
}
You can capture the registration code in a shell variable like this :
CN=$(aws iot get-registration-code | jq --raw-output .registrationCode)
Step 3 : Create the CA certificate (using the registration code)
Notice you only need to provide a CN here. nothing else.
openssl genrsa -out privateKeyVerification.key 2048
openssl req -new -key privateKeyVerification.key -subj "/CN=$CN" -out privateKeyVerification.csr
openssl x509 -req -in privateKeyVerification.csr -CA cacert.pem -CAkey cacert.key -CAcreateserial -out privateKeyVerification.crt -days 365 -sha256

Related

How to use Common Name as parameter while creating Server certificate

I am new to Linux and i am currently trying to create server certificates from CA.crt.
I have Certificate parameter to be used are CN (common name) = ipaddress and 1 year validity. I know how to use validity parameter but don't know what is improtance of CN and how can i use it while creating server certificate? See below command i am using
//create a certificate request .csr
openssl req -new -out server.csr -key server.key
//CA key to verify and sign the server certificate
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
Some common information
'CN(Common Name)' is one of the parameters in the 'Subject' of the certificate.
Others being C(Country), ST(State), OU(Organization Unit), etc.
'Subject' usually includes the information about the entity to which the certificate has been issued to.
To specify CN for a certificate, you can specify it while generating the CSR.
Answer to your question
Assuming you have to generate server.crt with CN=<ip_address>, you will have to generate CSR as follows (change ip as needed):
openssl req -new -out server2.csr -key server.key -subj "/CN=255.255.255.255"
Alternatively, if -subj option is not provided, an interactive mode window should open where you can specify the desired CN in 'Common Name' field. If you wish to skip other parameters like ST, OU in the subject, put '.' to skip them in the interactive mode.
Hope this helps.

self sign certificate : extract values into conf file

I'm creating self signed certificate. It is one ssl sertificate for several local domains:
local.dev.lat.com
local.dev.bet.com
local.dev.cat.com
local.dev.mon.com
local.dev.pop.com
...
I have this command for creating that:
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout server.key \
-out server.crt \
-subj "/CN=*.local.dev.lat.com,*.local.dev.bet.com" \
-addext "subjectAltName=DNS:*.local.dev.bet.com,DNS:local.dev.bet.com,DNS:*.local.dev.bet.com,DNS:local.dev.bet.com,IP:127.0.0.1"
My question is:
as I have around 30 domains I would like to extract -subj and -addext params to conf file somehow. Is it possible?
Let's make CERT="server.crt"; #or any other certificate.
You can easily get all of the requested info in one command openssl x509 -noout -in ${CERT} -text. You can parse that, but it's not ideal. Look at the man page for x509 for better options.
Note I am using bash to do variable substitution. You should too.
To get the serial:
serial=$(openssl x509 -serial -noout -in ${CERT}); #get only the serial
serial=${serial#*=}; #strip the 'serial=' header
To get the subject:
subject=$(openssl x509 -subject -noout -in ${CERT}); #get only the subject
subject=${subject#*=}; #strip the 'subject=' header
Now for the subjectAltName... It's an x509 extension, so it gets a bit trickier. But lets try anyways:
#use almost every certopt that exists to narrow display to X509v3 section
altname=$(openssl x509 -noout -in ${CERT} -text -certopt no_header,no_version,no_signame \
-certopt no_validity,no_subject,no_issuer,no_pubkey,no_sigdump,no_aux,no_serial)
#remove previous extensions, headers, and leading spaces
altname=${altname#*X509v3 Subject Alternative Name: $'\n' };
#remove any possible sections after
altname=${altname%%$'\n'*}
#unset the variable if subjectAltName didn't exist
[[ "${altname}" == " X509v3 extensions:" ]] && unset altname
Your mileage may vary whilst parsing altname. I just whipped this up in a few minutes, so I'm sure i missed some edge cases. Anyways...
Now you have three variables you can throw at anything however you want;
echo -e "${CERT}:\n Serial:\n ${serial}\n Subject:\n ${subject}\n subjectAltName:\n ${altname}"
That's it. Job done...
#there seems to be a pattern forming here
openssl ec -text -noout -check -in private.key #check private key
openssl req -text -noout -verify -in CSR.csr #check signing request
openssl x509 -text -noout -in public.crt #check public key
openssl pkcs12 -info -noout -in keyStore.p12 #check client cert
openssl crl -text -noout -in revocation.crl #check certificate revocation list

What is the role of the -signkey option in openssl-req?

openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -out server.crt -signkey server.key -days 3650
This is a popular command for generating self-signed SSL certificates using OpenSSL.
What confuses me is the -signkey parameter in the third command line, what is the use of this option? I don't see it in openssl req -help.
Can anyone answer it please? Thanks in advance!
Why are you looking at req's help? The third line is using x509 command:
]$ openssl x509 -help
...
-signkey infile Self sign cert with arg
So it is the key with which you self-sign the certificate.

Cannot connect IoT Hub using X509 CA certificate by mosquitto, paho

thank you for the great document. and tutorials.
I am still stack in connecting IoT Hub using mosquitto. I guess I set all of the option written here as clientId, Username, topic name. Are there any additional option should I add? thanks for your help!
$ openssl genrsa -out rootCA.key 2048
$ openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem
$ # Upload rootCA.pem to IoT Hub and get verification code
$ openssl genrsa -out verificationCert.key 2048
$ openssl req -new -key verificationCert.key -out verificationCert.csr
# create csr with CN=[verification code]
$ openssl x509 -req -in verificationCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out verificationCert.pem -days 500 -sha256
$ # upload verificationCert.pem and pass verificaton
$ openssl genrsa -out deviceCert.key 2048
$ openssl req -new -key deviceCert.key -out deviceCert.csr
$ openssl x509 -req -in deviceCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out deviceCert.pem -days 500 -sha256
$ # create Device in IoT Hub
$ mosquitto_pub -d -h $myhub.azure-devices.net -p 8883 --cafile /etc/ssl/certs/Baltimore_CyberTrust_Root.pem --cert ./deviceCert.pem --key ./deviceCert.key -i $mydevice -u "$myhub.azure-devices.net/$mydevice/?api-version=2018-06-30" -t "/devices/$mydevice/messages/events/" -m '{"message": "Hello IoT Hub!"}'
Client [deviceName] sending CONNECT
Error: The connection was lost.
I also failed by paho.
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#tlsssl-configuration
my code is following.
from paho.mqtt import client as mqtt
import ssl
path_to_root_cert = "/etc/ssl/certs/Baltimore_CyberTrust_Root.pem"
device_id = "mydevice"
iot_hub_name = "myhub"
def on_connect(client, userdata, flags, rc):
print("Device connected with result code: " + str(rc))
def on_disconnect(client, userdata, rc):
print("Device disconnected with result code: " + str(rc))
def on_publish(client, userdata, mid):
print("Device sent message")
client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
# Set the username but not the password on your client
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
device_id + "/?api-version=2018-06-30", password=None)
# Set the certificate and key paths on your client
cert_file = "./deviceCert.pem"
key_file = "./deviceCert.key"
client.tls_set(ca_certs=path_to_root_cert, certfile=cert_file, keyfile=key_file,
cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
# Connect as before
client.connect(iot_hub_name+".azure-devices.net", port=8883)
client.publish("devices/" + device_id + "/messages/events/", "{id=123}", qos=1)
client.loop_forever()
the result was following which means unauthorized.
Device connected with result code: 5
Device disconnected with result code: 5
JFYI, I could connect to AWS IoT using own CA cert by following step
$ openssl genrsa -out rootCA.key 2048
$ openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem
$ openssl genrsa -out verificationCert.key 2048
$ aws iot get-registration-code
$ openssl req -new -key verificationCert.key -out verificationCert.csr
$ openssl x509 -req -in verificationCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out verificationCert.pem -days 500 -sha256
$ # use the registration code as CN
$ aws iot register-ca-certificate --ca-certificate file://rootCA.pem --verification-cert file://verificationCert.pem
$ aws iot update-ca-certificate --certificate-id [id which got above] --new-status ACTIVE
$ openssl genrsa -out deviceCert.key 2048
$ openssl req -new -key deviceCert.key -out deviceCert.csr
$ openssl x509 -req -in deviceCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out deviceCert.pem -days 500 -sha256
$ aws iot register-certificate --certificate-pem file://deviceCert.pem --ca-certificate-pem file://rootCA.pem
$ aws iot update-certificate --certificate-id [id which got above] --new-status ACTIVE
$ mosquitto_pub -h [endpoint].iot.ap-northeast-1.amazonaws.com -p 8883 --cafile ./rootCA.pem --cert ./deviceCert.pem --key ./deviceCert.key -q 1 -d -t topic/test -i testdevice -m "Hello, World"
$ # rootCA is the CA I've got from https://www.amazontrust.com/repository/AmazonRootCA1.pem
I can connect just fine with mosquitto_pub, using the exact same steps as you to create the various keypairs. Note that you have a mistake in the topic, it should not start with a / (for your Paho sample, you got it right though).
A few things you should check:
can you confirm you provisioned your device in IoT hub as X.509 CA Signed, and not "self-signed"?
CN for your device cert should not contain special characters or white space, and you should use the exact same name (your $mydevice variable) as the Device ID to create the "X.509 CA Signed" device in your IoT Hub.

multiple key & CSR for different CN and same attributes

I need to generate new keys &CSR for 17 different CN: i.e. server1.com, server2.com ... server17.com but they all have the same attributes:
i.e. C=US, ST=State, L=Town, O=Online Coputers, OU=Support Operations, CN=server1.com/emailAddress=certificates#support.com
I generated CSR and key for CN server1.com using:
openssl req -out server1.com.csr -new -newkey rsa:2048 -nodes -keyout server1.com.key
and it works fine.
Is it possible to feed the attributes as constants to openssl and just change CN, would openssl support this ? in this way the command will generate keys and CSRs with same attributes but different CNs.
Does it make any sense?
for example, you have a list file with different CN (CN.txt)
server1.com
server2.com
serverx.com
servery.com
Then you can run below command to generate keys:
while read line
do
openssl req -out ${line}.csr -new -newkey rsa:2048 -nodes -keyout ${line}.key
done < CN.list

Resources