Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
feat: generate certificate JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
coderbyheart committed Aug 12, 2019
1 parent 64a9bad commit 71e8d12
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 20 deletions.
2 changes: 1 addition & 1 deletion cli/bifravst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const bifravstCLI = async () => {

const commands = [
registerCaCommand({ stackId, certsDir, region }),
generateCertCommand(),
generateCertCommand({ endpoint }),
connectCommand({ endpoint, deviceUiUrl, certsDir }),
reactConfigCommand({ stackId, region }),
cdCommand({ region }),
Expand Down
6 changes: 0 additions & 6 deletions cli/commands/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ export const connectCommand = ({
certsDir: string
}): ComandDefinition => ({
command: 'connect <deviceId>',
options: [
{
flags: '-e, --endpoint <endpoint>',
description: 'MQTT broker endpoint',
},
],
action: async (deviceId: string) =>
connect({
deviceId,
Expand Down
32 changes: 30 additions & 2 deletions cli/commands/generate-cert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import { ComandDefinition } from './CommandDefinition'
import { randomWords } from '@bifravst/random-words'
import * as path from 'path'
import { generateDeviceCertificate } from '../jitp/generateDeviceCertificate'
import { deviceFileLocations } from '../jitp/deviceFileLocations'

export const generateCertCommand = (): ComandDefinition => ({
export const generateCertCommand = ({
endpoint,
}: {
endpoint: string
}): ComandDefinition => ({
command: 'generate-cert',
options: [
{
Expand All @@ -14,9 +19,12 @@ export const generateCertCommand = (): ComandDefinition => ({
],
action: async ({ deviceId }: { deviceId: string }) => {
const id = deviceId || (await randomWords({ numWords: 3 })).join('-')
const certsDir = path.resolve(process.cwd(), 'certificates')
await generateDeviceCertificate({
endpoint,
deviceId: id,
certsDir: path.resolve(process.cwd(), 'certificates'),
certsDir,
caCert: path.resolve(process.cwd(), 'data', 'AmazonRootCA1.pem'),
log: (...message: any[]) => {
console.log(...message.map(m => chalk.magenta(m)))
},
Expand All @@ -27,7 +35,27 @@ export const generateCertCommand = (): ComandDefinition => ({
console.log(
chalk.green(`Certificate for device ${chalk.yellow(id)} generated.`),
)
console.log()
console.log(chalk.green('You can now connect to the broker.'))
console.log()
console.log(
chalk.gray('Use the file'),
chalk.yellow(deviceFileLocations({ certsDir, deviceId }).json),
)
console.log(
chalk.gray('with the'),
chalk.blue.italic('Certificate Manager'),
chalk.gray('in the'),
chalk.blue('nRF Connect for Desktop'),
chalk.gray('app'),
chalk.blue.italic('LTE Link Monitor'),
)
console.log(chalk.gray('to flash the certificate onto the device.'))
console.log(
chalk.gray(
'https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Connect-for-desktop',
),
)
},
help: 'Generate a certificate for a device, signed with the CA.',
})
2 changes: 1 addition & 1 deletion cli/device/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const connect = async (args: {
caCert: string
}) => {
const { deviceId, deviceUiUrl, certsDir, endpoint, caCert } = args
const deviceFiles = deviceFileLocations(certsDir, deviceId)
const deviceFiles = deviceFileLocations({ certsDir, deviceId })
let cfg = defaultConfig

console.log(chalk.blue('Device ID: '), chalk.yellow(deviceId))
Expand Down
9 changes: 8 additions & 1 deletion cli/jitp/deviceFileLocations.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import * as path from 'path'

export const deviceFileLocations = (certsDir: string, deviceId: string) => ({
export const deviceFileLocations = ({
certsDir,
deviceId,
}: {
certsDir: string
deviceId: string
}) => ({
key: path.resolve(certsDir, `device-${deviceId}.key`),
csr: path.resolve(certsDir, `device-${deviceId}.csr`),
cert: path.resolve(certsDir, `device-${deviceId}.pem`),
certWithCA: path.resolve(certsDir, `device-${deviceId}.bundle.pem`),
json: path.resolve(certsDir, `device-${deviceId}.json`),
})
43 changes: 34 additions & 9 deletions cli/jitp/generateDeviceCertificate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ import { run } from '../process/run'
* Generates a certificate for a device, signed with the CA
* @see https://docs.aws.amazon.com/iot/latest/developerguide/device-certs-your-own.html
*/
export const generateDeviceCertificate = async (args: {
export const generateDeviceCertificate = async ({
endpoint,
certsDir,
log,
debug,
deviceId,
caCert,
}: {
endpoint: string
certsDir: string
deviceId: string
caCert: string
log: (...message: any[]) => void
debug: (...message: any[]) => void
}): Promise<{ deviceId: string }> => {
const { certsDir, log, debug, deviceId } = args

try {
await fs.stat(certsDir)
} catch {
Expand All @@ -24,7 +31,10 @@ export const generateDeviceCertificate = async (args: {

log(`Generating certificate for device ${deviceId}`)
const caFiles = caFileLocations(certsDir)
const deviceFiles = deviceFileLocations(certsDir, deviceId)
const deviceFiles = deviceFileLocations({
certsDir,
deviceId,
})

await run({
command: 'openssl',
Expand Down Expand Up @@ -68,12 +78,27 @@ export const generateDeviceCertificate = async (args: {
log: debug,
})

const certWithCa = (await Promise.all([
fs.readFile(deviceFiles.cert),
fs.readFile(caFiles.cert),
])).join(os.EOL)

await fs.writeFile(deviceFiles.certWithCA, certWithCa, 'utf-8')

// Writes the JSON file which works with the Certificate Manager of the LTA Link Monitor
await fs.writeFile(
deviceFiles.certWithCA,
(await Promise.all([
fs.readFile(deviceFiles.cert),
fs.readFile(caFiles.cert),
])).join(os.EOL),
deviceFiles.json,
JSON.stringify(
{
caCert: await fs.readFile(caCert, 'utf-8'),
clientCert: certWithCa,
privateKey: await fs.readFile(deviceFiles.key, 'utf-8'),
clientId: deviceId,
brokerHostname: endpoint,
},
null,
2,
),
'utf-8',
)

Expand Down

0 comments on commit 71e8d12

Please sign in to comment.