WriteMsroots Method
WriteMsroots(ReadOnlySpan<Byte>)
Write contents
to the MSROOTS data objects. This will replace
any data already stored in the MSROOTS data objects.
public void WriteMsroots(ReadOnlySpan<byte> contents)
Parameters
Type | Name | Description |
---|---|---|
System.ReadOnlySpan<System.Byte> | contents | The data to store, represented as a |
Exceptions
Type | Condition |
---|---|
System.ArgumentOutOfRangeException | The input data was too long. |
System.InvalidOperationException | There is no |
MalformedYubiKeyResponseException | The YubiKey returned malformed data and authentication, either single or double, could not be performed. |
System.OperationCanceledException | The user canceled management key collection. |
System.Security.SecurityException | Mutual authentication was performed and the YubiKey was not authenticated. |
Remarks
The YubiKey PIV application can store data objects. There is a set of data elements defined by the PIV standard. See the User's Manual entry on GET DATA for information on these elements and their tags. The standard also allows for vendor-defined data objects. MSROOTS is one such vendor-defined element.
The intention of the MSROOTS data object is to store (and retrieve) a PKCS 7 constuction containing a set of root certificates. These certificates will make it easier for the SDK to interface with the Microsoft Smart Card Base Crypto Service Provider (CSP).
Very few applications will need to use this feature. If you don't already know what the MSROOTS are, how to use them, and that they are part of your application already, then you almost certainly will never need to use this method.
This method will take whatever data it is given and store it on the YubiKey under the tag "MSROOTS". This method will not verify that the data is a PKCS 7 construction, or that it contains root certificates, it will simply write the bytes given.
Note that in order to store any data on the YubiKey, it must be formatted as a TLV (tag-length-value):
tag || length || value
for example, it might be
53 20 (contents, 32 bytes)
or
7F 61 20 (contents, 32 bytes)
The tag used varies depending on the data being stored. This method
builds the TLV. That is, the caller supplies the contents only, this
method will format it into a construction the YubiKey expects. This
method knows what tag to use for MSROOTS and how to specify the
length.
Note also that there is a limit to the number of bytes that can be stored in a data object. If the contents to store is longer, then this method will break the data into blocks and store each block in a different data object. The caller simply supplies all the data as a single byte array, this method will take care of the bookkeeping of breaking it into blocks and storing them in separate data objects.
There is a limit on the number of data objects, however, so there is indeed a limit on the total size of the data.
There is a limit of 5 MSROOTS data objects
The limit on data length for each data object is
pre 4.0 YubiKeys (e.g. NEO) : 2030 bytes
4.0 and later YubiKeys : 2800 bytes
The total input limit is
pre 4.0 YubiKeys (e.g. NEO) : 2030*5 bytes : 10,150
4.0 and later YubiKeys : 2800*5 bytes : 14,000
If the data passed in is too long, this method will throw an
exception.
Note that the input is a ReadOnlySpan
. If you have the data in
a byte array (byte[]
), just pass it in as the argument, it
will be cast to a ReadOnlySpan
automatically. Also, if you
have no data to store (which is the same as DeleteMsroots
),
you can pass in null
, but the preferred input in this case is
ReadOnlySpan.Empty
.
Input with a length of 0 is equivalent to calling
DeleteMsroots
.
In order to perform this operation, the management key must be
authenticated during this session. If it has not been authenticated,
this method will call AuthenticateManagementKey(Boolean). That
is, your application does not need to authenticate the management key
separately (i.e., call TryAuthenticateManagementKey
or
AuthenticateManagementKey
), this method will determine if the
management key has been authenticated or not, and if not, it will
make the call to perform mutual authentication.
The authentication method will collect the management key using the
KeyCollector
delegate. If no such delegate has been set, it
will throw an exception.
The KeyCollector
has an option to cancel the operation. That
is, the AuthenticateManagementKey
method will call the
KeyCollector
requesting the management key, and it is possible
that during the collection operations, the user cancels. The
KeyCollector
will return to the authentication method noting
the cancellation. In that case, it will throw an exception. If you
want the authentication to return false
on user cancellation,
you must call TryAuthenticateManagementKey(Boolean) directly
before calling this method.