-
Notifications
You must be signed in to change notification settings - Fork 252
NuGet Sign Command
Status: Review
Task for Specing and Task for execution
Currently there is no way for package authors to sign their packages. Signed packages help with authenticity and integrity of a package when it is being consumed by NuGet users. Further, in future, this command will also facilitate package sources to sign the package to prevent package tampering once it has been published.
All NuGet package authors.
Part of the larger package signing effort.
We will add a first level command to NuGet.exe which will allow package authors and package sources to sign NuGet packages.
usage: NuGet sign [package] [options]
Signs a NuGet package.
argument:
package - Path to the package that needs to be signed.
options:
-CertificatePath - Path to the certificate to be used while signing the certificate. The path can be a file path or a certificate path from the local store of the format cert:\certificate_context\certificate_store_name\certificate_thumb_print.
-CertificateSubjectName - String representing the subject name of the certificate used to search the default local certificate store for the certificate. The search is a case-insensitive string comparison using the supplied value, which will find all certificates with the subject name containing that string, regardless of other subject values.
-CertificateFingerprint - SHA-1 fingerprint of the certificate used to search the default local certificate store for the certificate.
-CertificatePassphrase - Password for the certificate, if needed.
This option can be used to specify the password for the certificate.
-CryptographicServiceProvider - Name of the Cryptographic Service Provider which contains the Private Key Container.
This option, along with -KeyContainer, can be used to specify the private key if the certificate file does not contain one.
-KeyContainer - Name of the Key Container which has the Private Key.
This option, along with -CryptographicServiceProvider, can be used to specify the private key if the certificate file does not contain one.
-Timestamper - URL to an RFC-3161 compliant trusted time-stamping server.
-HashingAlgorithm - Hashing algorithm to be used. Defaults to SHA512.
-RSASignaturePadding - RSA Padding scheme used to sign the package with an RSA certificate. Supported padding schemes are PKCS1-v1.5 and PSS.
This option can be used to specify the padding scheme if the certificate is not signed with either of the two supported schemes.
-Force - Switch to indicate if the current signature should be overwritten. By default the command will fail if the package already has a signature.
-OutputDirectory - Directory where the signed package should be saved. By default the original package is overwritten by the signed package.
- The options
CertificatePath
,CertificateSubjectName
andCertificateFingerprint
are different options available to the user to specify a certificate. - The
CertificatePath
option is used to uniquely identify a certificate. The parameter accepts a file path or a certificate path from the local store in the following format -cert:\certificate_context\certificate_store_name\certificate_thumb_print
. -
CertificateSubjectName
andCertificateFingerprint
options can be used to search the local certificate store. While searching the local store, if more than one matching certificates are found then we should prompt the user with the options and ask them to provide a more specific filter. - In all the cases we should display the certificate being used.
- Users will have 2 options for providing the private key to be used to sign the package. Primarily they could provide a certificate which contains a proivate key, in such case we will use that to sign the package. However, if the certificate does not contain a private key then the user can provide the
CryptographicServiceProvider
andKeyContainer
values to be used to find the private key. - While providing
CryptographicServiceProvider
andKeyContainer
values, the user must ensure that the resolved private key must match the certificate file passed. Else the sign command will fail. -
Force
option can be used to specify if an existing signature should be overwritten. If this switch is not used then we should fail if there is an existing signature.
The command will support for the following certificates sources -
- Certificate file - Path to the certificate file on the local file system or a network share.
- Certificate store/keychain - A URI to the certificate in the local certificate store or keychain by using a URI format -
cert:\certificate_context\certificate_store_name\certificate_thumb_print
orcert:\path_to_keychain\certificate_thumb_print
- Hardware Security Module - Under Investigation.
- CNG/CSP - User can provide the Cryptographic Service Provider name and the key container name. Sample Code
The sign command should be atomic in nature i.e. If the command fails then the original package should not be modified. Possible options for this -
- Do not allow in-place signing and mandate the
-OutputDirectory
options. - Back up the original package and overwrite it back if signing fails midway. This can be costly for large packages.
The sign command should perform the following validations before attempting to sign the package -
- Validate that the package exists on disk and the process has Read/Write access to the package.
- If -OutputDirectory if passed, validate that the process has write access to the path.
In future we would like to add support for the following platforms -
-
Dotnet CLI -
dotnet nuget sign <package_path> [Options]
-
MSBuild target -
msbuild /t:nugetsign <package_path> [Options]
The sign command will do the following -
- Check if the passed arguments are valid. If not then throw.
- Wrap them into a
SignArgs
object. - Invoke
var signResult = SignCommandRunner.Execute(SignArgs);
. - If
signResult.Status == Failure
, then show an error indicating the failure.
The SignCommandRunner will do the following -
- Convert the package path into an in memory Package Object/stream.
- Convert the certificate into an in memory Certificate object.
- Pass the SignArgs to NuGet.Sign API.
- return result to the caller.
1. Whats the best way to pass the certificate password to the sign command?
Currently the spec only accepts a commandline switch with clear text password. But we can also support having an
encrypted password stored in a nuget.config file.
2. What kind of validation will we do before signing?
We should spec out all the validations that will be done before signing.
3. Do we need to add retry mechanism for the timestamper service?
Number of retries to get a timestamp for the countersignature.
Delay (in seconds) between the retries to get a timestamp for the countersignature.
Please use the tracking issue to provide feedback or any questions that you might have. Thanks!
Check out the proposals in the accepted
& proposed
folders on the repository, and active PRs for proposals being discussed today.