Reputation: 74066
I am trying to connect to Google's MQTT server but I am getting errors I created all the certificates and registered my device (Adafruit huzzah32)
and the documentation says you connect to mqtt.googleapis.com:8883
So I do
WiFiClientSecure wifi;
MQTTClient client;
client.begin("mqtt.googleapis.com", 8883, wifi);
When I try to connect I use the device path
const char* jwt = "{json web token}";
const char* device = "projects/{project-id}/locations/{cloud-region}/registries/{registry-id}/devices/{device-id}";
Serial.print("Connecting to mqtt");
while (!client.connect(device,"unused",jwt)) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.println("Connected to mqtt");
but it never connects
I verified the google certificate by calling
openssl s_client -showcerts -connect mqtt.googleapis.com:8883
and I put in my RSA Private key and certificate key that was made
wifi.setCACert(googleCertificate2);
wifi.setCertificate(myCertificate);
wifi.setPrivateKey(privateCert);
What am I doing wrong?
Here is the connection documentation https://cloud.google.com/iot/docs/how-tos/mqtt-bridge
Update
I made a quick java example to see if I can connect going off the example they have for connecting and I get a MqttException
saying Bad user name or password (4)
Here is the code for that
private void doStuff(){
String clientId = String.format("ssl://%s:%s", "mqtt.googleapis.com", 8883);
String mqttClientId = String.format("projects/%s/locations/%s/registries/%s/devices/%s","{project_id}", "us-central1", "{register}", "{device}");
MqttConnectOptions connectOptions = new MqttConnectOptions();
connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
Properties sslProps = new Properties();
sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
connectOptions.setSSLProperties(sslProps);
connectOptions.setUserName("unused");
try{
String jwt = createJwtRsa("{project-id}");
connectOptions.setPassword(jwt.toCharArray());
MqttClient client = new MqttClient(clientId, mqttClientId, new MemoryPersistence());
while(!client.isConnected()){
try{
client.connect(connectOptions);
}catch (MqttException e) {
e.printStackTrace();
}
}
Log.d("","");
}catch (Exception e){
e.printStackTrace();
}
}
private String createJwtRsa(String projectId) throws Exception {
DateTime now = new DateTime();
JwtBuilder jwtBuilder =
Jwts.builder().setIssuedAt(now.toDate()).setExpiration(now.plusDays(1000000).toDate()).setAudience(projectId);
byte[] keyBytes = readBytes(getAssets().open("rsa_private_pkcs8"));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey k = kf.generatePrivate(spec);
return jwtBuilder.signWith(SignatureAlgorithm.RS256, k).compact();
}
As you can see here I have the IoT service acount added to IAM
Does that mean my keys that I generated with openssl are incorrect?
Upvotes: 0
Views: 2353
Reputation: 76879
here the IAM roles are being explained ...the paragraph here sounds alike what you describe:
On the IAM page in Google Cloud Platform Console, verify that the role Cloud IoT Core Service Agent appears in the Members list for the relevant project service account. (Look for the project service account that ends in @gcp-sa-cloudiot.iam.gserviceaccount.com.)
If the Cloud IoT Core Service Agent role does not appear in the Members list, use gcloud to add the cloudiot.serviceAgent role to the relevant project service account. This role includes permission to publish to Pub/Sub topics.
if not yet having installed it, the Cloud SDK is required for all those gcloud
CLI commands, which can be used to list & edit the configurations (of which all can be done through the console, as well)... it's maybe easier, because all of the examples there use it, too.
update ...
concerning JWT refresh tokens, see this article or have some Q & A or the specification: JSON Web Token (JWT), JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants. here's another relevant article: https://medium.com/google-cloud/refreshing-json-web-tokens-jwts-for-google-cloud-iot-core-897318df3836
Upvotes: 0
Reputation: 74066
My problem ended up being that I was trying to set a really large expiration date on my Json Web Token (on purpose so I didnt have to keep generating new ones since I have not found a way to do that in arduino) and it looks like that google's mqtt server does not accept anything over a day so the keys will have to be updated daily.
Also inorder to connect to the MQTT server I had to change the buffer size of the MqttClient on the arduino to have a buffer size of 1024 bytes.
MQTTClient client(1024);
anything less I would get an error saying buffer isnt big enough.
Upvotes: 1