Skip to content

Latest commit

 

History

History
125 lines (98 loc) · 7.95 KB

File metadata and controls

125 lines (98 loc) · 7.95 KB

The CoseSign1 library is a .NET Standard 2.0 library (for maximum compatibility) for CoseSign1Message object creation leveraging the abstractions provided by CoseSign1.Abstractions package. The library consists of two distinct usage models offered by two distinct classes. CoseSign1MessageFactory is provided for dependency injection or direct usage patterns while CoseSign1MessageBuilder is provided to match a more builder style consumption model.

This library performs the basic creation (signing) of a CoseSign1Message object with no validation or constraints imposed. It should be used in conjunction with a concrete signing key provider implementation such as CoseSign1.Certificates to be of most use. At its core it provides the following functionality above the .Net native object types:

  • Allows for consistent extension of the Protected and Unprotected headers at time of signing operation
  • Allows both RSA and ECdsa signing key abstractions to be provided
  • Enforces content type is present with a valid, non-empty payload before creating the object.

Dependencies

CoseSign1 has the following package dependencies

  • CoseSign1.Abstractions

An implementation of CoseSign1.Interfaces.ICoseSign1MessageFactory over either Stream or Byte[] payloads. It provides a proper CoseSign1Message object in either full object, or byte[] form through the various methods in accordance with the interface contract.

A builder pattern implementation operating over ICoseSign1MessageFactory and ICoseSigningKeyProvider abstractions. It defaults to CoseSign1MessageFactory if none is specified and requires a provided ICoseSign1MessageFactory and ICoseSigningKeyProvider to provide the signing keys used for signing operations.

An example of creating a CoseSign1Message via the Factory pattern is provided below. Note The example uses the CoseSign1.Certificates.Local SigningKeyProvider for illustrative purposes only.

Synchronous API

using CoseSign1;
using CoseSign1.Certificates.Local;

...

byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!");
X509Certificate2CoseSigningKeyProvider coseSigningKeyProvider = new(...);
CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(
            payload: testPayload,
            signingKeyProvider: coseSigningKeyProvider,
            embedPayload: true,
            contentType: ContentTypeConstants.Cose);

Async API

The factory also provides async methods for all operations, particularly useful when:

  • Working with streams
  • Integrating with cloud-based signing services
  • Need cancellation support
  • Operating in async contexts
using CoseSign1;
using CoseSign1.Certificates.Local;

...

// Async signing with byte array payload
byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!");
X509Certificate2CoseSigningKeyProvider coseSigningKeyProvider = new(...);
CancellationToken cancellationToken = ...; // Optional

CoseSign1Message response = await coseSign1MessageFactory.CreateCoseSign1MessageAsync(
            payload: testPayload,
            signingKeyProvider: coseSigningKeyProvider,
            embedPayload: true,
            contentType: ContentTypeConstants.Cose,
            cancellationToken: cancellationToken);

// Async signing with stream payload
using Stream payloadStream = File.OpenRead("large-file.bin");

CoseSign1Message streamResponse = await coseSign1MessageFactory.CreateCoseSign1MessageAsync(
            payload: payloadStream,
            signingKeyProvider: coseSigningKeyProvider,
            embedPayload: false,
            contentType: ContentTypeConstants.Cose,
            cancellationToken: cancellationToken);

// Get bytes directly instead of CoseSign1Message object
byte[] signatureBytes = await coseSign1MessageFactory.CreateCoseSign1MessageBytesAsync(
            payload: testPayload,
            signingKeyProvider: coseSigningKeyProvider,
            embedPayload: false,
            contentType: ContentTypeConstants.Cose,
            cancellationToken: cancellationToken);

See Advanced.md for more details on async patterns.

An example of creating a CoseSign1Message via the builder pattern is provided below. Note The example uses the CoseSign1.Certificates.Local SigningKeyProvider for illustrative purposes only.

Synchronous API

using CoseSign1;
using CoseSign1.Certificates.Local;

...

byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!");
X509Certificate2CoseSigningKeyProvider coseSigningKeyProvider = new(...);
CoseSign1MessageBuilder CoseSign1Builder = new(coseSigningKeyProvider);
CoseSign1Message response = CoseSign1Builder.SetPayloadBytes(testPayload)
                                            .SetContentType(ContentTypeConstants.Cose)
                                            .ExtendCoseHeader(mockedHeaderExtender.Object)
                                            .Build();

Async API

The builder also supports async building with cancellation:

using CoseSign1;
using CoseSign1.Certificates.Local;

...

byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!");
X509Certificate2CoseSigningKeyProvider coseSigningKeyProvider = new(...);
CancellationToken cancellationToken = ...; // Optional

CoseSign1MessageBuilder CoseSign1Builder = new(coseSigningKeyProvider);
CoseSign1Message response = await CoseSign1Builder.SetPayloadBytes(testPayload)
                                                   .SetContentType(ContentTypeConstants.Cose)
                                                   .ExtendCoseHeader(mockedHeaderExtender.Object)
                                                   .BuildAsync(cancellationToken);

See Advanced.md for more details on async patterns.