Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for public sign to csc #6776

Merged
merged 8 commits into from
Nov 17, 2015
Merged

Add support for public sign to csc #6776

merged 8 commits into from
Nov 17, 2015

Conversation

agocke
Copy link
Member

@agocke agocke commented Nov 13, 2015

Sometimes called "fake sign" or "OSS sign" public signing is including
the public key in an output assembly and setting the "signed" flag, but
not actually signing the assembly with a private key. This is useful for
open source projects where people want to build assemblies which are
compatible with the released "fully signed" assemblies, but don't have
access to the private key used to sign the assemblies. Since almost no
consumers actually need to check if the assembly is fully signed, these
publicly built assemblies are useable in almost every scenario that the
fully signed one would be used in.

This PR implements support only for C# -- VB will be added soon. If
being used at the command line, the /publicsign flag can be passed to
csc and the /keyfile flag can specify the public key. Unlike fully
signing, a full key pair encoded in the SNK file format is not currently
supported. When using /publicsign, just the public key must be in the
/keyfile file.

When using the API, the public key can be passed directly using the
CryptoPublicKey CompilationOption.

Sometimes called "fake sign" or "OSS sign" public signing is including
the public key in an output assembly and setting the "signed" flag, but
not actually signing the assembly with a private key. This is useful for
open source projects where people want to build assemblies which are
compatible with the released "fully signed" assemblies, but don't have
access to the private key used to sign the assemblies. Since almost no
consumers actually need to check if the assembly is fully signed, these
publicly built assemblies are useable in almost every scenario that the
fully signed one would be used in.

This PR implements support only for C# -- VB will be added soon. If
being used at the command line, the /publicsign flag can be passed to
csc and the /keyfile flag can specify the public key. Unlike fully
signing, a full key pair encoded in the SNK file format is not currently
supported. When using /publicsign, just the public key must be in the
/keyfile file.

When using the API, the public key can be passed directly using the
CryptoPublicKey CompilationOption.
@agocke
Copy link
Member Author

agocke commented Nov 13, 2015

@dotnet/roslyn-compiler @tmat Please review

@agocke
Copy link
Member Author

agocke commented Nov 14, 2015

@davidfowl FYI. This change also requires the PublicSign option to be set, so if you were using just the CryptoPublicKey option to indicate that you wanted OSS signing, you'll need to add this flag to ASP.NET

@davidfowl
Copy link
Member

@agocke That's a breaking change. Can we infer public sign from providing the bytes only? It's going to break omnisharp as well (well only if we update roslyn there)

/cc @moozzyk

@davidfowl
Copy link
Member

@agocke Where is the code that extracts only the public key from the keyfile? Specifically https://github.com/aspnet/dnx/blob/72b0f325959a06d7b9d92aa438df0dc889a73ec3/src/Microsoft.Dnx.Compilation.CSharp.Common/SnkUtils.cs

@agocke
Copy link
Member Author

agocke commented Nov 14, 2015

@davidfowl It is a breaking change, but we never intended for that to be the indicator that public signing was enabled.

For the parser splitting, there is no code for that yet. I'm currently writing a parser that should get rid of all our uses of IStrongName.GetPublicKey, but this is the quickest way to get the functionality without the parser -- the public key must just be written to the file, instead of the public/private key pair.

@davidfowl
Copy link
Member

@agocke So to get the same functionality we have in dnx today there needs to be some other process that extracts the public key from a real snk file, writes it on disk, and then hand it into csc?

@tmat
Copy link
Member

tmat commented Nov 14, 2015

@agocke I would still prefer not to have an extra option and do OSS signing automatically when the .snk file only contains public key. To keep it simple. The chances of using accidentally .snk file with public key only instead of full key are low, same as accidentally using a different key than intended.

@agocke
Copy link
Member Author

agocke commented Nov 14, 2015

@davidfowl I believe you already have an SNK parser and pass the key to the CryptoPublicKey option. You can do the same thing now, just also set PublicKey sign to true. Is that a big ask?

@davidfowl
Copy link
Member

I'd rather not write a temp file to disk. The compiler can extract it from the existing file on disk and do that in memory.

@agocke
Copy link
Member Author

agocke commented Nov 14, 2015

@davidfowl Are we still talking about DNX? Since you construct your compilation options in memory you don't have to write the public key out to disk -- just pass it to CryptoPublickKey here:

public ImmutableArray<byte> CryptoPublicKey { get; protected set; }

@agocke
Copy link
Member Author

agocke commented Nov 14, 2015

@davidfowl I would also say that most public sign consumers would just store the public key in a file split out from the snk file, since the snk file couldn't be checked into version control, but the public key can.

@agocke
Copy link
Member Author

agocke commented Nov 14, 2015

test prtest/win/dbg/unit64 please

@agocke
Copy link
Member Author

agocke commented Nov 16, 2015

@tmat @davidfowl Added a key blob parser.

Unfortunately, completely removing the StrongNameProvider.CreateKeys API is more complicated -- DesktopStrongNameProvider takes an optional list of key file search paths, which are searched for the key files. Since DesktopStrongNameProvider is public, removing this method of signing may be a breaking change. I may need to go to the compat council for this one.

parsedArgs = DefaultParse(new[] { "/publicsign:-", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(
// error CS2007: Unrecognized option: '/publicsign:-'
Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/publicsign:-").WithLocation(1, 1));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting

@@ -9,6 +9,7 @@
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.Interop;
using Roslyn.Utilities;
using System.Threading;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: sort usings

@@ -0,0 +1,312 @@
using Microsoft.CodeAnalysis.Collections;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing copyright

@agocke
Copy link
Member Author

agocke commented Nov 16, 2015

@dotnet/roslyn-compiler Ping -- please review

@AlekseyTs
Copy link
Contributor

LGTM

generalDiagnosticOption,
specificDiagnosticOptions,
concurrentBuild,
deterministic:=False,' TODO: fix this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe have a issue number for this TODO?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO was there when I copied this code. I don't know what's to be done here -- @TyOverby did you originally leave this TODO?

@@ -473,6 +492,8 @@ protected override CompilationOptions CommonWithPlatform(Platform platform)
return WithPlatform(platform);
}

protected override CompilationOptions CommonWithPublicSign(bool publicSign) => WithPublicSign(publicSign);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong preference between => and {} for single line methods. But it does irk the OCD part of my brain when we have types that mix the two styles with identical code. I think we should keep the existing style in this file or move everything to =>

@jaredpar
Copy link
Member

Is there a bug filed for the MSBuild work needed as the follow up to this change?

@moozzyk
Copy link

moozzyk commented Nov 17, 2015

LGTM

@agocke
Copy link
Member Author

agocke commented Nov 17, 2015

@jaredpar I was going to file bugs for the follow-on work after it was merged.

@agocke
Copy link
Member Author

agocke commented Nov 17, 2015

@jaredpar Was that a +1 ;)

@jaredpar
Copy link
Member

@agocke it was a 👍 assuming you fixed the other feedback but it oloks like you have now so yes 👍

agocke added a commit that referenced this pull request Nov 17, 2015
Add support for public sign to csc
@agocke agocke merged commit 7672019 into dotnet:master Nov 17, 2015
@agocke agocke deleted the AddFakeSign branch November 17, 2015 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants