0

I have an IoT device which is failing to establish a connection with the cloud. The problem is related to the device X509 certificate (to the best of my understanding). I've posted a version of this question in the general stackoverflow to appeal to AWS specialists, but thought it could be rephrased in more general terms and be of interest in this forum. The problem can be best summed up by showing a few pieces of evidence.

The API request

"eventSource": "iot.amazonaws.com",
"eventName": "RegisterThing",
"errorCode": "InvalidRequestException",
"errorMessage": "Invalid registration template. Cannot resolve reference value: {Ref=AWS::IoT::Certificate::Country}",
"parameters": {
    "AWS::IoT::Certificate::CommonName": "testThingC\\=US",
    "AWS::IoT::Certificate::Id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYY",
    "AWS::IoT::Certificate::SerialNumber": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYY"
}

It's clear from the API request that the common name and country are messed up. Common name should be "testThing" and the country should be "US". This request comes from the device which is loaded with a certificate and key. Then in the cloud, the CA certificate is used to validate the request.

Create CA

CN=${1:-root}
COUNTRY=${2:-US}
LOCATION=${3:-NewYork}
STATE=${4:-NewYork}
ORG=${5:-SuperDuperStuff}
ORGUNIT=${6:-RandD}

openssl genrsa -out "$CN.ca.key" 2048
openssl req -x509 -new -nodes -key "$CN.ca.key" -sha256 -days 9125 -out "$CN.ca.pem"  -subj "//CN=$CN\C=$COUNTRY\L=$LOCATION\ST=$STATE\O=$ORG\OU=$ORGUNIT"

Create Device Cert

DEVICE=$1
openssl genrsa -out "$DEVICE.key" 2048
openssl req -new -key "$DEVICE.key" -out "$DEVICE.csr"  -subj "//CN=$DEVICE\C=US"
openssl x509 -req -in $DEVICE.csr -CA "./caCredentials/$CA.ca.pem" -CAkey "./caCredentials/$CA.ca.key" -CAcreateserial -out "$DEVICE.crt.tmp" -days 9125 -sha256

Q1) What is the purpose of the common name and country parameters? Are they essential elements? Q2) Is it possible to discern where the problem comes from based on the evidence provided (if it all looks right, I would modify the question to ask what would you need to change in order to recreate the problem? Q3) Could it be coming from the CA or the device certificate or both? Q4) And lastly, is it possible to fix this without changing anything on the device itself - by modifying the CA certificate such that the API request and subsequent validation will work?

I hope this is an interesting puzzle for you security folk.

4
  • I can't believe you; every version of OpenSSL I have (which is quite a few) rejects that format of -subj (beginning with two slashes). If I instead use one slash I can more or less reproduce the problem, which occurs because all the components (technically RDNs) should be separated by normal (forward) slash / NOT BACKSLASH \ . This takes approximately 2 seconds to read in the man page so no it is not very interesting. What name components AWS requires (or allows) is up to them; there is no universal standard. Oct 4, 2023 at 23:41
  • (added) ... except for one basic rule: the name of a child/subordinate CA or an end-entity (EE) like your device, must be DIFFERENT from the name of the CA that issues the cert for that entity. However, except for the bogus syntax, you have that. Oct 4, 2023 at 23:48
  • Thanks Dave. I'm using boiler plate code so you will excuse me for not recognising an incorrectly formatted argument. If I understand your comment correctly, you believe that incorrectly writing it as follows would result in the error I am seeing: -subj "/CN=$DEVICE\C=US". Would that be in the CA or the device? I know this is probably easy for you, but I do appreciate your comments.
    – monkey
    Oct 5, 2023 at 1:55
  • @monkey Just replace it with -subj "/CN=$DEVICE/C=US". OpenSSL uses / as the field separator in the -subj option, not \. \ is also an escape character in most shells, so it's probably being stripped out before the shell even calls your openssl command. What ends up being passed to openssl if you use \ will just be -subj "//CN=testThingC=US". EDIT: Oh, of course markdown uses backslash as an escape character. Oct 5, 2023 at 20:25

1 Answer 1

1

Regarding question 1

Common Name, Country and the other value are certificate attributes. You can put strings in there.

Technical:

As far as X.509 is concerned (see RFC5280), the contents of DN elements are irrelevant beyond equality comparisons; which means that you can put whatever sequence of characters you wish, as long as you do so consistently. [2]

Some people pass DNS-Names as CN, but this is official deprecated by IETF and CA/Browser Forums. DNS-Names should be set as SAN-Extension (Subject Alternative Names). You can read more about this in RFC6125, Section 2.3.

Placing a DNS name or server name in the Common Name (CN) is deprecated by both the IETF and CA/Browser Forums. Though deprecated, it's currently not prohibited. The CA/B is important because that's what browsers follow - browsers do not follow the IETF. [4]

For server certificates, it is also relevant that end users can see the corresponding values when they read the certificate (e.g., via the browser). The country code with exactly two characters is always passed as the country attribute.

Summary:

Nowadays there might be a legal requirement to fill in such data accurately but there is no technical reason to enter it aside from auditing and for use by humans. [5]

If you want to read more about the historical context of this metadata, you can look at this thread.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .