Skip to content

Commit

Permalink
Merge pull request #22 from sigstore/signer-utils
Browse files Browse the repository at this point in the history
Add signer utilities
  • Loading branch information
loosebazooka authored May 19, 2022
2 parents d30406d + 31b4af1 commit 79c31ef
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 27 deletions.
49 changes: 49 additions & 0 deletions src/main/java/dev/sigstore/encryption/signers/EcdsaSigner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2022 The Sigstore Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sigstore.encryption.signers;

import java.nio.charset.Charset;
import java.security.*;

/** ECDSA signer, use {@link Signers#newEcdsaSigner()} to instantiate}. */
public class EcdsaSigner implements Signer {

private final KeyPair keyPair;

EcdsaSigner(KeyPair keyPair) {
this.keyPair = keyPair;
}

@Override
public PublicKey getPublicKey() {
return keyPair.getPublic();
}

@Override
public byte[] sign(String content, Charset charset)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
return sign(content.getBytes(charset));
}

@Override
public byte[] sign(byte[] content)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(keyPair.getPrivate());
signature.update(content);
return signature.sign();
}
}
43 changes: 43 additions & 0 deletions src/main/java/dev/sigstore/encryption/signers/Signer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2022 The Sigstore Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sigstore.encryption.signers;

import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SignatureException;

/** A signing helper that wraps common signing operations for use within this library. */
public interface Signer {

/** Return the public key associated with this signer. */
PublicKey getPublicKey();

/**
* Sign the content. Implementations should use an algorithm that hashes with sha256 before
* signing.
*/
byte[] sign(String content, Charset charset)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException;

/**
* Sign the content. Implementations should use an algorithm that hashes with sha256 before
* signing.
*/
byte[] sign(byte[] content)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException;
}
30 changes: 30 additions & 0 deletions src/main/java/dev/sigstore/encryption/signers/Signers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2022 The Sigstore Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sigstore.encryption.signers;

import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;

/** Factory class for creation of signers. */
public class Signers {

/** Create a new ECDSA signer with 256 bit keysize */
public static EcdsaSigner newEcdsaSigner() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(256);
return new EcdsaSigner(keyGen.generateKeyPair());
}
}
36 changes: 9 additions & 27 deletions src/test/java/dev/sigstore/fulcio/client/FulcioClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
*/
package dev.sigstore.fulcio.client;

import dev.sigstore.encryption.signers.Signers;
import dev.sigstore.testing.FakeCTLogServer;
import dev.sigstore.testing.FulcioWrapper;
import dev.sigstore.testing.MockOAuth2ServerExtension;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -39,19 +37,11 @@ public void testSigningCert(
var token = mockOAuthServerExtension.getOidcToken().getIdToken();
var subject = mockOAuthServerExtension.getOidcToken().getEmailAddress();

// create an ECDSA p-256 keypair, this is our key that we want to generate certs for
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(256);
KeyPair keys = keyGen.generateKeyPair();
var signer = Signers.newEcdsaSigner();
var signed = signer.sign(subject, StandardCharsets.UTF_8);

// sign the "subject" with our key, this signer already generates asn1 notation
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(keys.getPrivate());
signature.update(subject.getBytes(StandardCharsets.UTF_8));
byte[] signed = signature.sign();

// create a certificate request with our public key, oidc token and our signed "subject"
CertificateRequest cReq = new CertificateRequest(keys.getPublic(), token, signed);
// create a certificate request with our public key and our signed "subject"
CertificateRequest cReq = new CertificateRequest(signer.getPublicKey(), token, signed);

// ask fulcio for a signing cert
SigningCertificate sc = c.SigningCert(cReq);
Expand All @@ -73,19 +63,11 @@ public void testSigningCert_NoSct(
var token = mockOAuthServerExtension.getOidcToken().getIdToken();
var subject = mockOAuthServerExtension.getOidcToken().getEmailAddress();

// create an ECDSA p-256 keypair, this is our key that we want to generate certs for
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(256);
KeyPair keys = keyGen.generateKeyPair();

// sign the "subject" with our key, this signer already generates asn1 notation
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(keys.getPrivate());
signature.update(subject.getBytes(StandardCharsets.UTF_8));
byte[] signed = signature.sign();
var signer = Signers.newEcdsaSigner();
var signed = signer.sign(subject, StandardCharsets.UTF_8);

// create a certificate request with our public key, oidc token and our signed "subject"
CertificateRequest cReq = new CertificateRequest(keys.getPublic(), token, signed);
// create a certificate request with our public key and our signed "subject"
CertificateRequest cReq = new CertificateRequest(signer.getPublicKey(), token, signed);

// ask fulcio for a signing cert
SigningCertificate sc = c.SigningCert(cReq);
Expand Down

0 comments on commit 79c31ef

Please sign in to comment.