Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AxisIPCamera/Client/AxisHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public CertificateData ListCertificates()
/// <summary>
/// Gets the default keystore configured on the device.
/// </summary>
/// <returns>Keystore Enum</returns>
/// <returns>Keystore struct</returns>
public Constants.Keystore GetDefaultKeystore()
{
try
Expand Down
6 changes: 4 additions & 2 deletions AxisIPCamera/Inventory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
Expand Down Expand Up @@ -47,7 +48,8 @@ public JobResult ProcessJob(InventoryJobConfiguration config, SubmitInventoryUpd
_logger.MethodEntry();

_logger.LogTrace($"Begin Inventory for Client Machine {config.CertificateStoreDetails.ClientMachine}...");
_logger.LogDebug($"Inventory Config: {JsonConvert.SerializeObject(config)}");
string jsonConfig = JsonConvert.SerializeObject(config);
_logger.LogDebug($"Inventory Config: {jsonConfig.Replace(config.ServerPassword,"**********")}");

_logger.LogTrace("Create HTTPS client to connect to device");
var client = new AxisHttpClient(config, config.CertificateStoreDetails, Resolver);
Expand All @@ -63,7 +65,7 @@ public JobResult ProcessJob(InventoryJobConfiguration config, SubmitInventoryUpd
// Get the default keystore
_logger.LogTrace("Retrieve the default keystore");
Constants.Keystore defaultKeystore = client.GetDefaultKeystore();
string defaultKeystoreString = Enum.GetName(typeof(Constants.Keystore), defaultKeystore);
string defaultKeystoreString = defaultKeystore.ToString();
_logger.LogDebug($"Inventory - Default keystore: {defaultKeystoreString}");

// Create new list of client certs that are only tied to the default keystore
Expand Down
3 changes: 2 additions & 1 deletion AxisIPCamera/Management.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
// to determine if job should overwrite an existing certificate in the store, for example a renewal.

// Retrieve management config from Command
_logger.LogDebug($"Management Config {JsonConvert.SerializeObject(config)}");
string jsonConfig = JsonConvert.SerializeObject(config);
_logger.LogDebug($"Management Config: {jsonConfig.Replace(config.ServerPassword,"**********")}");
_logger.LogDebug($"Client Machine: {config.CertificateStoreDetails.ClientMachine}");

// Get needed information from config
Expand Down
2 changes: 1 addition & 1 deletion AxisIPCamera/Model/Certificate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Certificate
{
[JsonProperty("alias")] public string Alias { get; set; }
[JsonProperty("certificate")] public string CertAsPem { get; set; }
[JsonProperty("keystore")] public Constants.Keystore Keystore { get; set; }
[JsonProperty("keystore")] public Constants.Keystore Keystore { get; init; }
public Constants.CertificateUsage Binding { get; set; } = Constants.CertificateUsage.Other;
}

Expand Down
43 changes: 39 additions & 4 deletions AxisIPCamera/Model/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

using System;
using System.IO;
using Newtonsoft.Json;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;

Expand Down Expand Up @@ -55,11 +56,15 @@ public enum CertificateUsage
Undefined
}

// ** NOTE: There may be more keystore types depending on the Axis camera model
public enum Keystore
/** NOTE: Keystore IDs are device-specific and not stable across Axis camera models.
* New camera/firmware can introduce new Keystore IDs. Cameras can also have multiple
* keystores of the same type (i.e. SE0, SE1, TPM0, TPM1, etc.)
* Therefore, treat the Keystore ID as an opaque string, not a fixed enum.
*/
[JsonConverter(typeof(KeystoreJsonConverter))]
public readonly record struct Keystore(string Value)
{
TEE0, // Trusted Environment
SE0 // Secure Element
public override string ToString() => Value;
}

public enum ApiType
Expand Down Expand Up @@ -212,5 +217,35 @@ public static void ValidateCsr(string csrPem)
throw new Exception($"CSR Validation failed: {ex.Message}");
}
}

/// <summary>
/// Custom JSON converter to tell Newtonsoft how to parse the record struct 'Keystore' type.
/// </summary>
private sealed class KeystoreJsonConverter : JsonConverter<Keystore>
{
public override Keystore ReadJson(
JsonReader reader,
Type objectType,
Keystore existingValue,
bool hasExistingValue,
JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
return new Keystore(reader.Value!.ToString()!);
}

throw new JsonSerializationException(
$"Unexpected token {reader.TokenType} when parsing Keystore");
}

public override void WriteJson(
JsonWriter writer,
Keystore value,
JsonSerializer serializer)
{
writer.WriteValue(value.Value);
}
}
}
}
5 changes: 3 additions & 2 deletions AxisIPCamera/Reenrollment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public JobResult ProcessJob(ReenrollmentJobConfiguration config, SubmitReenrollm
_logger.MethodEntry();

_logger.LogTrace($"Begin Reenrollment for Client Machine {config.CertificateStoreDetails.ClientMachine}");
_logger.LogDebug($"Reenrollment Config: {JsonConvert.SerializeObject(config)}");
string jsonConfig = JsonConvert.SerializeObject(config);
_logger.LogDebug($"Reenrollment Config: {jsonConfig.Replace(config.ServerPassword,"**********")}");

// Log each key-value pair in the Job Properties for debugging
_logger.LogDebug("Begin Job Properties ---");
Expand Down Expand Up @@ -109,7 +110,7 @@ public JobResult ProcessJob(ReenrollmentJobConfiguration config, SubmitReenrollm
// Get the default keystore
_logger.LogTrace("Retrieve the default keystore");
Constants.Keystore defaultKeystore = client.GetDefaultKeystore();
string defaultKeystoreString = Enum.GetName(typeof(Constants.Keystore), defaultKeystore);
string defaultKeystoreString = defaultKeystore.ToString();
_logger.LogDebug($"Reenrollment - Default keystore: {defaultKeystoreString}");

_logger.LogTrace("Generating self-signed cert with private key on device");
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v1.0.2
- fix(logs): Removed logging of plaintext cert store Server Password
- fix(keystore): Updated Keystore type to be dynamic instead of a fixed Enum to allow compatibility across different cameras/firmware

v1.0.1
- chore(docs): Add screenshots to docs

Expand Down
47 changes: 43 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,37 @@ the Keyfactor Command Portal

![AxisIPCamera Custom Fields Tab](docsource/images/AxisIPCamera-custom-fields-store-type-dialog.png)


###### Server Username
Enter the username of the configured "service" user on the camera


> [!IMPORTANT]
> This field is created by the `Needs Server` on the Basic tab, do not create this field manually.




###### Server Password
Enter the password of the configured "service" user on the camera


> [!IMPORTANT]
> This field is created by the `Needs Server` on the Basic tab, do not create this field manually.




###### Use SSL
Select True or False depending on if SSL (HTTPS) should be used to communicate with the camera. This should always be "True"

![AxisIPCamera Custom Field - ServerUseSsl](docsource/images/AxisIPCamera-custom-field-ServerUseSsl-dialog.png)
![AxisIPCamera Custom Field - ServerUseSsl](docsource/images/AxisIPCamera-custom-field-ServerUseSsl-validation-options-dialog.png)





##### Entry Parameters Tab

| Name | Display Name | Description | Type | Default Value | Entry has a private key | Adding an entry | Removing an entry | Reenrolling an entry |
Expand All @@ -197,21 +228,29 @@ the Keyfactor Command Portal

![AxisIPCamera Entry Parameters Tab](docsource/images/AxisIPCamera-entry-parameters-store-type-dialog.png)


##### Certificate Usage
The Certificate Usage to assign to the cert after enrollment. Can be left 'Other' to be assigned later.

![AxisIPCamera Entry Parameter - CertUsage](docsource/images/AxisIPCamera-entry-parameters-store-type-dialog-CertUsage.png)
![AxisIPCamera Entry Parameter - CertUsage](docsource/images/AxisIPCamera-entry-parameters-store-type-dialog-CertUsage-validation-options.png)



</details>

## Installation

1. **Download the latest AXIS IP Camera Universal Orchestrator extension from GitHub.**

Navigate to the [AXIS IP Camera Universal Orchestrator extension GitHub version page](https://github.com/Keyfactor/axis-ipcamera-orchestrator/releases/latest). Refer to the compatibility matrix below to determine whether the `net6.0` or `net8.0` asset should be downloaded. Then, click the corresponding asset to download the zip archive.
Navigate to the [AXIS IP Camera Universal Orchestrator extension GitHub version page](https://github.com/Keyfactor/axis-ipcamera-orchestrator/releases/latest). Refer to the compatibility matrix below to determine the asset should be downloaded. Then, click the corresponding asset to download the zip archive.

| Universal Orchestrator Version | Latest .NET version installed on the Universal Orchestrator server | `rollForward` condition in `Orchestrator.runtimeconfig.json` | `axis-ipcamera-orchestrator` .NET version to download |
| --------- | ----------- | ----------- | ----------- |
| Older than `11.0.0` | | | `net6.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net6.0` | | `net6.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `Disable` | `net6.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `LatestMajor` | `net8.0` |
| `11.6` _and_ newer | `net8.0` | | `net8.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `Disable` | `net6.0` || Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `LatestMajor` | `net8.0` |
| `11.6` _and_ newer | `net8.0` | | `net8.0` |

Unzip the archive containing extension assemblies to a known location.

Expand Down
2 changes: 2 additions & 0 deletions integration-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"update_catalog": true,
"link_github": true,
"description": "The Axis IP Camera Orchestrator Extension is used to inventory, manage Trust certs, and enroll for client certificates that can be bound to endpoints.",
"short_description": "The Axis IP Camera Orchestrator Extension is used to inventory, manage Trust certs, and enroll for client certificates that can be bound to endpoints.",
"about": {
"orchestrator": {
"UOFramework": "10.1",
Expand Down Expand Up @@ -90,3 +91,4 @@
}
}
}

Loading