CA: Stub IssueCertificateForPrecertificate(). (#2973)

Stub out IssueCertificateForPrecertificate() enough so that we can continue with the PRs that implement & test it in parallel with PRs that implement and test the calling side (via mock implementations of the CA side).
This commit is contained in:
Brian Smith 2017-08-15 13:50:21 -10:00 committed by Roland Bracewell Shoemaker
parent ca2df597f9
commit e670e6e6b5
8 changed files with 192 additions and 38 deletions

View File

@ -441,6 +441,12 @@ func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
}, nil
}
func (ca *CertificateAuthorityImpl) IssueCertificateForPrecertificate(ctx context.Context, req *caPB.IssueCertificateForPrecertificateRequest) (core.Certificate, error) {
emptyCert := core.Certificate{}
return emptyCert, berrors.InternalServerError("IssueCertificateForPrecertificate is not implemented")
}
func (ca *CertificateAuthorityImpl) generateNotAfterAndSerialNumber() (time.Time, *big.Int, error) {
notAfter := ca.clk.Now().Add(ca.validityPeriod)

View File

@ -114,10 +114,23 @@ var (
// OIDExtensionCTPoison is defined in RFC 6962 s3.1.
OIDExtensionCTPoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3}
// The "certificate-for-precertificate" tests use the precertificate from a
// previous "precertificate" test, in order to verify that the CA is
// stateless with respect to these two operations, since a separate CA
// object instance will be used for generating each. Consequently, the
// "precertificate" tests must be before the "certificate-for-precertificate"
// tests in this list, and we cannot run these sub-tests concurrently.
//
// In order to test the case where the same CA object is used for issuing
// both the precertificate and the certificate, we'd need to contort
// |TestIssueCertificate| quite a bit, and since it isn't clear that that
// would be useful, we've avoided adding that case, at least for now.
issuanceModes = []IssuanceMode{
{name: "non-precertificate", usePrecertificateFlow: false, enablePrecertificateFlow: false},
{name: "precertificate", usePrecertificateFlow: true, enablePrecertificateFlow: true},
{name: "precertificate-disabled", usePrecertificateFlow: true, enablePrecertificateFlow: false},
{name: "non-precertificate", issuePrecertificate: false, issueCertificateForPrecertificate: false, enablePrecertificateFlow: false},
{name: "precertificate", issuePrecertificate: true, issueCertificateForPrecertificate: false, enablePrecertificateFlow: true},
{name: "precertificate-disabled", issuePrecertificate: true, issueCertificateForPrecertificate: false, enablePrecertificateFlow: false},
{name: "certificate-for-precertificate", issuePrecertificate: false, issueCertificateForPrecertificate: true, enablePrecertificateFlow: true},
{name: "certificate-for-precertificate-disabled", issuePrecertificate: false, issueCertificateForPrecertificate: true, enablePrecertificateFlow: false},
}
)
@ -292,9 +305,10 @@ type TestCertificateIssuance struct {
}
type IssuanceMode struct {
name string
usePrecertificateFlow bool
enablePrecertificateFlow bool
name string
issuePrecertificate bool
issueCertificateForPrecertificate bool
enablePrecertificateFlow bool
}
func TestIssueCertificate(t *testing.T) {
@ -317,6 +331,11 @@ func TestIssueCertificate(t *testing.T) {
}
for _, testCase := range testCases {
// The loop through |issuanceModes| must be inside the loop through
// |testCases| because the "certificate-for-precertificate" tests use
// the precertificates previously generated from the preceding
// "precertificate" test. See also the comment above |issuanceModes|.
precertDER := []byte{}
for _, mode := range issuanceModes {
ca, sa := testCase.setup(t)
ca.enablePrecertificateFlow = mode.enablePrecertificateFlow
@ -328,7 +347,7 @@ func TestIssueCertificate(t *testing.T) {
issueReq := &caPB.IssueCertificateRequest{Csr: testCase.csr, RegistrationID: &arbitraryRegID}
certDER := []byte{}
if mode.usePrecertificateFlow {
if mode.issuePrecertificate {
response, err := ca.IssuePrecertificate(ctx, issueReq)
if !mode.enablePrecertificateFlow {
@ -338,8 +357,23 @@ func TestIssueCertificate(t *testing.T) {
test.AssertNotError(t, err, "Failed to issue precertificate")
certDER = response.Precert.Der
precertDER = certDER
} else {
coreCert, err := ca.IssueCertificate(ctx, issueReq)
coreCert := core.Certificate{}
if mode.issueCertificateForPrecertificate {
coreCert, err = ca.IssueCertificateForPrecertificate(ctx,
&caPB.IssueCertificateForPrecertificateRequest{
IssueReq: issueReq,
PrecertDER: precertDER,
})
if true { // TODO(briansmith): !mode.enablePrecertificateFlow
test.AssertError(t, err, "Precertificate flow not disabled as expected")
return
}
} else {
coreCert, err = ca.IssueCertificate(ctx, issueReq)
}
test.AssertNotError(t, err, "Failed to issue certificate")
certDER = coreCert.DER
@ -351,7 +385,7 @@ func TestIssueCertificate(t *testing.T) {
test.AssertNotError(t, err, "Certificate failed to parse")
poisonExtension := findExtension(cert.Extensions, OIDExtensionCTPoison)
test.AssertEquals(t, mode.usePrecertificateFlow, poisonExtension != nil)
test.AssertEquals(t, mode.issuePrecertificate, poisonExtension != nil)
if poisonExtension != nil {
test.AssertEquals(t, poisonExtension.Critical, true)
test.AssertDeepEquals(t, poisonExtension.Value, []byte{0x05, 0x00}) // ASN.1 DER NULL
@ -616,12 +650,12 @@ func TestInvalidCSRs(t *testing.T) {
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to create CA")
ca.enablePrecertificateFlow = mode.usePrecertificateFlow
ca.enablePrecertificateFlow = mode.issuePrecertificate
t.Run(mode.name+"-"+testCase.name, func(t *testing.T) {
serializedCSR := mustRead(testCase.csrPath)
issueReq := &caPB.IssueCertificateRequest{Csr: serializedCSR, RegistrationID: &arbitraryRegID}
if !mode.usePrecertificateFlow {
if !mode.issuePrecertificate {
_, err = ca.IssueCertificate(ctx, issueReq)
} else {
_, err = ca.IssuePrecertificate(ctx, issueReq)
@ -630,7 +664,7 @@ func TestInvalidCSRs(t *testing.T) {
test.Assert(t, berrors.Is(err, berrors.Malformed), "Incorrect error type returned")
test.AssertEquals(t, signatureCountByPurpose("cert", ca.signatureCount), 0)
if mode.usePrecertificateFlow == mode.enablePrecertificateFlow {
if mode.issuePrecertificate == mode.enablePrecertificateFlow {
test.AssertError(t, err, testCase.errorMessage)
if testCase.check != nil {
testCase.check(t, ca, sa)
@ -762,7 +796,7 @@ func issueCertificateSubTestUnknownExtension(t *testing.T, i *TestCertificateIss
// NOTE: The hard-coded value here will have to change over time as Boulder
// adds new (unrequested) extensions to certificates.
expectedExtensionCount := 9
if i.mode.usePrecertificateFlow {
if i.mode.issuePrecertificate {
expectedExtensionCount += 1
}
test.AssertEquals(t, len(i.cert.Extensions), expectedExtensionCount)

View File

@ -11,6 +11,7 @@ It is generated from these files:
It has these top-level messages:
IssueCertificateRequest
IssuePrecertificateResponse
IssueCertificateForPrecertificateRequest
GenerateOCSPRequest
OCSPResponse
*/
@ -87,6 +88,43 @@ func (m *IssuePrecertificateResponse) GetSctFetchingConfig() *core.SCTFetchingCo
return nil
}
type IssueCertificateForPrecertificateRequest struct {
IssueReq *IssueCertificateRequest `protobuf:"bytes,1,opt,name=issueReq" json:"issueReq,omitempty"`
PrecertDER []byte `protobuf:"bytes,2,opt,name=precertDER" json:"precertDER,omitempty"`
SCTs [][]byte `protobuf:"bytes,3,rep,name=SCTs" json:"SCTs,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *IssueCertificateForPrecertificateRequest) Reset() {
*m = IssueCertificateForPrecertificateRequest{}
}
func (m *IssueCertificateForPrecertificateRequest) String() string { return proto1.CompactTextString(m) }
func (*IssueCertificateForPrecertificateRequest) ProtoMessage() {}
func (*IssueCertificateForPrecertificateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{2}
}
func (m *IssueCertificateForPrecertificateRequest) GetIssueReq() *IssueCertificateRequest {
if m != nil {
return m.IssueReq
}
return nil
}
func (m *IssueCertificateForPrecertificateRequest) GetPrecertDER() []byte {
if m != nil {
return m.PrecertDER
}
return nil
}
func (m *IssueCertificateForPrecertificateRequest) GetSCTs() [][]byte {
if m != nil {
return m.SCTs
}
return nil
}
type GenerateOCSPRequest struct {
CertDER []byte `protobuf:"bytes,1,opt,name=certDER" json:"certDER,omitempty"`
Status *string `protobuf:"bytes,2,opt,name=status" json:"status,omitempty"`
@ -98,7 +136,7 @@ type GenerateOCSPRequest struct {
func (m *GenerateOCSPRequest) Reset() { *m = GenerateOCSPRequest{} }
func (m *GenerateOCSPRequest) String() string { return proto1.CompactTextString(m) }
func (*GenerateOCSPRequest) ProtoMessage() {}
func (*GenerateOCSPRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (*GenerateOCSPRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *GenerateOCSPRequest) GetCertDER() []byte {
if m != nil {
@ -136,7 +174,7 @@ type OCSPResponse struct {
func (m *OCSPResponse) Reset() { *m = OCSPResponse{} }
func (m *OCSPResponse) String() string { return proto1.CompactTextString(m) }
func (*OCSPResponse) ProtoMessage() {}
func (*OCSPResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (*OCSPResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *OCSPResponse) GetResponse() []byte {
if m != nil {
@ -148,6 +186,7 @@ func (m *OCSPResponse) GetResponse() []byte {
func init() {
proto1.RegisterType((*IssueCertificateRequest)(nil), "ca.IssueCertificateRequest")
proto1.RegisterType((*IssuePrecertificateResponse)(nil), "ca.IssuePrecertificateResponse")
proto1.RegisterType((*IssueCertificateForPrecertificateRequest)(nil), "ca.IssueCertificateForPrecertificateRequest")
proto1.RegisterType((*GenerateOCSPRequest)(nil), "ca.GenerateOCSPRequest")
proto1.RegisterType((*OCSPResponse)(nil), "ca.OCSPResponse")
}
@ -165,6 +204,7 @@ const _ = grpc.SupportPackageIsVersion4
type CertificateAuthorityClient interface {
IssueCertificate(ctx context.Context, in *IssueCertificateRequest, opts ...grpc.CallOption) (*core.Certificate, error)
IssuePrecertificate(ctx context.Context, in *IssueCertificateRequest, opts ...grpc.CallOption) (*IssuePrecertificateResponse, error)
IssueCertificateForPrecertificate(ctx context.Context, in *IssueCertificateForPrecertificateRequest, opts ...grpc.CallOption) (*core.Certificate, error)
}
type certificateAuthorityClient struct {
@ -193,11 +233,21 @@ func (c *certificateAuthorityClient) IssuePrecertificate(ctx context.Context, in
return out, nil
}
func (c *certificateAuthorityClient) IssueCertificateForPrecertificate(ctx context.Context, in *IssueCertificateForPrecertificateRequest, opts ...grpc.CallOption) (*core.Certificate, error) {
out := new(core.Certificate)
err := grpc.Invoke(ctx, "/ca.CertificateAuthority/IssueCertificateForPrecertificate", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for CertificateAuthority service
type CertificateAuthorityServer interface {
IssueCertificate(context.Context, *IssueCertificateRequest) (*core.Certificate, error)
IssuePrecertificate(context.Context, *IssueCertificateRequest) (*IssuePrecertificateResponse, error)
IssueCertificateForPrecertificate(context.Context, *IssueCertificateForPrecertificateRequest) (*core.Certificate, error)
}
func RegisterCertificateAuthorityServer(s *grpc.Server, srv CertificateAuthorityServer) {
@ -240,6 +290,24 @@ func _CertificateAuthority_IssuePrecertificate_Handler(srv interface{}, ctx cont
return interceptor(ctx, in, info, handler)
}
func _CertificateAuthority_IssueCertificateForPrecertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IssueCertificateForPrecertificateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CertificateAuthorityServer).IssueCertificateForPrecertificate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ca.CertificateAuthority/IssueCertificateForPrecertificate",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CertificateAuthorityServer).IssueCertificateForPrecertificate(ctx, req.(*IssueCertificateForPrecertificateRequest))
}
return interceptor(ctx, in, info, handler)
}
var _CertificateAuthority_serviceDesc = grpc.ServiceDesc{
ServiceName: "ca.CertificateAuthority",
HandlerType: (*CertificateAuthorityServer)(nil),
@ -252,6 +320,10 @@ var _CertificateAuthority_serviceDesc = grpc.ServiceDesc{
MethodName: "IssuePrecertificate",
Handler: _CertificateAuthority_IssuePrecertificate_Handler,
},
{
MethodName: "IssueCertificateForPrecertificate",
Handler: _CertificateAuthority_IssueCertificateForPrecertificate_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "ca/proto/ca.proto",
@ -324,27 +396,31 @@ var _OCSPGenerator_serviceDesc = grpc.ServiceDesc{
func init() { proto1.RegisterFile("ca/proto/ca.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 348 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x41, 0x4f, 0xf2, 0x40,
0x10, 0x86, 0x29, 0x7c, 0x7c, 0xc8, 0x80, 0x48, 0x17, 0x94, 0x06, 0x0e, 0x36, 0x4d, 0x4c, 0x38,
0x95, 0xa4, 0x57, 0x13, 0x13, 0x2c, 0x6a, 0x48, 0x4c, 0x24, 0xa0, 0x07, 0xbd, 0x6d, 0xd6, 0x01,
0x1a, 0x93, 0x2e, 0xee, 0x4e, 0x8d, 0xfe, 0x2e, 0xff, 0xa0, 0xe9, 0xb6, 0x98, 0x62, 0xd0, 0xdb,
0x36, 0x6f, 0xf7, 0x99, 0x79, 0x9f, 0x16, 0x6c, 0xc1, 0x47, 0x1b, 0x25, 0x49, 0x8e, 0x04, 0xf7,
0xcd, 0x81, 0x95, 0x05, 0xef, 0x1f, 0x0b, 0xa9, 0x70, 0x1b, 0x48, 0x85, 0x59, 0xe4, 0x5d, 0x40,
0x6f, 0xaa, 0x75, 0x82, 0x21, 0x2a, 0x8a, 0x96, 0x91, 0xe0, 0x84, 0x73, 0x7c, 0x4d, 0x50, 0x13,
0x6b, 0x40, 0x45, 0x68, 0xe5, 0x58, 0xae, 0x35, 0x6c, 0xb2, 0x13, 0x68, 0x29, 0x5c, 0x45, 0x9a,
0x14, 0xa7, 0x48, 0xc6, 0xd3, 0x89, 0x53, 0x76, 0xad, 0x61, 0xc5, 0x7b, 0x87, 0x81, 0xb9, 0x3f,
0x53, 0x28, 0x8a, 0x08, 0xbd, 0x91, 0xb1, 0x46, 0x76, 0x06, 0xb5, 0x4d, 0x96, 0x18, 0x4e, 0x23,
0xe8, 0xfa, 0x66, 0xf8, 0xee, 0xeb, 0x2c, 0x00, 0x5b, 0x0b, 0xba, 0x46, 0x12, 0xeb, 0x28, 0x5e,
0x85, 0x32, 0x5e, 0x46, 0x2b, 0x33, 0xa0, 0x11, 0xf4, 0xb2, 0x0b, 0x8b, 0xf0, 0x7e, 0x37, 0xf6,
0x1e, 0xa1, 0x73, 0x83, 0x31, 0x2a, 0x4e, 0x78, 0x17, 0x2e, 0x66, 0xdb, 0xad, 0x8f, 0xa0, 0x96,
0x92, 0x27, 0x57, 0xf3, 0x7c, 0xf3, 0x16, 0xfc, 0xd7, 0xc4, 0x29, 0xd1, 0x06, 0x58, 0x4f, 0x9f,
0x15, 0x72, 0x2d, 0x63, 0xa7, 0xe2, 0x5a, 0xc3, 0x2a, 0xb3, 0xa1, 0xae, 0xf0, 0x4d, 0xbe, 0xe0,
0xf3, 0x98, 0x9c, 0x7f, 0xa6, 0x94, 0x0b, 0xcd, 0x0c, 0x99, 0xb7, 0x68, 0xc3, 0x81, 0xca, 0xcf,
0x19, 0x34, 0xf8, 0xb4, 0xa0, 0x5b, 0x50, 0x36, 0x4e, 0x68, 0x2d, 0x55, 0x44, 0x1f, 0x6c, 0x02,
0xed, 0x9f, 0x3e, 0xd9, 0xc0, 0x17, 0xdc, 0xff, 0xc5, 0x72, 0xdf, 0xce, 0xfa, 0x15, 0x12, 0xaf,
0xc4, 0x1e, 0xa0, 0xb3, 0xc7, 0xea, 0xdf, 0xa0, 0xd3, 0xef, 0x70, 0xff, 0xb7, 0xf0, 0x4a, 0xc1,
0x2d, 0x1c, 0xa6, 0xbd, 0x72, 0x6d, 0x52, 0xb1, 0x73, 0x68, 0x16, 0x1d, 0xb2, 0x5e, 0xca, 0xd8,
0x63, 0xb5, 0xdf, 0x4e, 0x83, 0xa2, 0x13, 0xaf, 0x74, 0x59, 0x7b, 0xaa, 0x9a, 0x7f, 0xe8, 0x2b,
0x00, 0x00, 0xff, 0xff, 0x0b, 0x4b, 0x68, 0xdb, 0x72, 0x02, 0x00, 0x00,
// 408 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x53, 0xdf, 0xaf, 0xd2, 0x30,
0x14, 0x66, 0xec, 0x5e, 0xb9, 0xf7, 0x30, 0xaf, 0xac, 0xf7, 0x2a, 0x0b, 0x3c, 0x38, 0x97, 0x98,
0xec, 0x41, 0x47, 0xb2, 0x57, 0x13, 0x13, 0x1c, 0x62, 0x48, 0x4c, 0x24, 0x80, 0x0f, 0xfa, 0xd6,
0xd4, 0x03, 0x34, 0x26, 0x2b, 0xb4, 0x9d, 0xd1, 0xf8, 0xa7, 0xf8, 0xcf, 0x9a, 0xb5, 0xc3, 0x0c,
0x32, 0xf0, 0xad, 0xcb, 0xd7, 0xf3, 0x9d, 0xef, 0xc7, 0x0a, 0x3e, 0xa3, 0xa3, 0x9d, 0x14, 0x5a,
0x8c, 0x18, 0x4d, 0xcc, 0x81, 0xb4, 0x19, 0x1d, 0x3c, 0x65, 0x42, 0xe2, 0x01, 0x10, 0x12, 0x2d,
0x14, 0xbd, 0x85, 0xfe, 0x4c, 0xa9, 0x02, 0x33, 0x94, 0x9a, 0xaf, 0x39, 0xa3, 0x1a, 0x17, 0xb8,
0x2f, 0x50, 0x69, 0xd2, 0x05, 0x97, 0x29, 0x19, 0x38, 0xa1, 0x13, 0x7b, 0xe4, 0x19, 0xdc, 0x49,
0xdc, 0x70, 0xa5, 0x25, 0xd5, 0x5c, 0xe4, 0xb3, 0x49, 0xd0, 0x0e, 0x9d, 0xd8, 0x8d, 0x7e, 0xc2,
0xd0, 0xcc, 0xcf, 0x25, 0xb2, 0x3a, 0x85, 0xda, 0x89, 0x5c, 0x21, 0x79, 0x09, 0x9d, 0x9d, 0x45,
0x0c, 0x4f, 0x37, 0x7d, 0x48, 0xcc, 0xf2, 0xe3, 0xeb, 0x24, 0x05, 0x5f, 0x31, 0x3d, 0x45, 0xcd,
0xb6, 0x3c, 0xdf, 0x64, 0x22, 0x5f, 0xf3, 0x8d, 0x59, 0xd0, 0x4d, 0xfb, 0x76, 0x60, 0x99, 0xad,
0x8e, 0xe1, 0xe8, 0x37, 0xc4, 0xa7, 0xca, 0xa7, 0x42, 0x9e, 0xea, 0xb0, 0x56, 0x5e, 0xc3, 0x0d,
0x2f, 0xef, 0x2e, 0x70, 0x5f, 0xe9, 0x18, 0x26, 0x8c, 0x26, 0xe7, 0x9c, 0x13, 0x80, 0x4a, 0xf5,
0xe4, 0xfd, 0xc2, 0xe8, 0xf0, 0x88, 0x07, 0x57, 0xcb, 0x6c, 0xa5, 0x02, 0x37, 0x74, 0x63, 0x2f,
0xfa, 0x02, 0xf7, 0x1f, 0x30, 0x47, 0x49, 0x35, 0x7e, 0xca, 0x96, 0xf3, 0xc3, 0xe0, 0x13, 0xe8,
0x1c, 0xa6, 0x6c, 0x6c, 0x77, 0xf0, 0x48, 0x69, 0xaa, 0x0b, 0x65, 0x58, 0x6e, 0xcb, 0x6f, 0x89,
0x54, 0x89, 0x3c, 0x70, 0x43, 0x27, 0xbe, 0x26, 0x3e, 0xdc, 0x4a, 0xfc, 0x21, 0xbe, 0xe3, 0xb7,
0xb1, 0x0e, 0xae, 0x4c, 0xa2, 0x21, 0x78, 0x96, 0xb2, 0x8a, 0xb0, 0x07, 0x37, 0xb2, 0x3a, 0x5b,
0xd2, 0xf4, 0x4f, 0x1b, 0x1e, 0x6a, 0xaa, 0xc7, 0x85, 0xde, 0x0a, 0xc9, 0xf5, 0x2f, 0x32, 0x81,
0xde, 0xa9, 0x25, 0x72, 0xc9, 0xe8, 0xc0, 0xb7, 0xe1, 0xd6, 0x90, 0xa8, 0x45, 0x3e, 0xc3, 0x7d,
0x43, 0xa5, 0x97, 0x89, 0x9e, 0xff, 0x03, 0x9b, 0x7f, 0x84, 0xa8, 0x45, 0xd6, 0xf0, 0xe2, 0xbf,
0x7d, 0x91, 0x57, 0x4d, 0x4b, 0xce, 0xd5, 0xda, 0x28, 0x3f, 0xfd, 0x08, 0x8f, 0xcb, 0xfc, 0xaa,
0x7a, 0x84, 0x24, 0x6f, 0xc0, 0xab, 0x77, 0x45, 0xfa, 0xe5, 0x8e, 0x86, 0xf6, 0x06, 0xbd, 0x12,
0xa8, 0x67, 0x1f, 0xb5, 0xde, 0x75, 0xbe, 0x5e, 0x9b, 0x87, 0xf2, 0x37, 0x00, 0x00, 0xff, 0xff,
0xb0, 0xc3, 0x4a, 0x62, 0x57, 0x03, 0x00, 0x00,
}

View File

@ -9,6 +9,7 @@ import "core/proto/core.proto";
service CertificateAuthority {
rpc IssueCertificate(IssueCertificateRequest) returns (core.Certificate) {}
rpc IssuePrecertificate(IssueCertificateRequest) returns (IssuePrecertificateResponse) {}
rpc IssueCertificateForPrecertificate(IssueCertificateForPrecertificateRequest) returns (core.Certificate) {}
}
// OCSPGenerator generates OCSP. We separate this out from
@ -29,6 +30,12 @@ message IssuePrecertificateResponse {
optional core.SCTFetchingConfig sctFetchingConfig = 2;
}
message IssueCertificateForPrecertificateRequest {
optional IssueCertificateRequest issueReq = 1;
optional bytes precertDER = 2;
repeated bytes SCTs = 3;
}
message GenerateOCSPRequest {
optional bytes certDER = 1;
optional string status = 2;

View File

@ -42,6 +42,10 @@ func (ca *mockCA) IssuePrecertificate(_ context.Context, _ *caPB.IssueCertificat
return nil, errors.New("IssuePrecertificate is not implemented by mockCA")
}
func (ca *mockCA) IssueCertificateForPrecertificate(_ context.Context, _ *caPB.IssueCertificateForPrecertificateRequest) (core.Certificate, error) {
return core.Certificate{}, errors.New("IssueCertificateForPrecertificate is not implemented by mockCA")
}
func (ca *mockCA) GenerateOCSP(_ context.Context, xferObj core.OCSPSigningRequest) (ocsp []byte, err error) {
ocsp = []byte{1, 2, 3}
time.Sleep(ca.sleepTime)

View File

@ -94,6 +94,9 @@ type CertificateAuthority interface {
// [RegistrationAuthority]
IssuePrecertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest) (*caPB.IssuePrecertificateResponse, error)
// [RegistrationAuthority]
IssueCertificateForPrecertificate(ctx context.Context, req *caPB.IssueCertificateForPrecertificateRequest) (Certificate, error)
GenerateOCSP(ctx context.Context, ocspReq OCSPSigningRequest) ([]byte, error)
}

View File

@ -51,6 +51,17 @@ func (cac CertificateAuthorityClientWrapper) IssuePrecertificate(ctx context.Con
return cac.inner.IssuePrecertificate(ctx, issueReq)
}
func (cac CertificateAuthorityClientWrapper) IssueCertificateForPrecertificate(ctx context.Context, req *caPB.IssueCertificateForPrecertificateRequest) (core.Certificate, error) {
if cac.inner == nil {
return core.Certificate{}, errors.New("this CA client does not support issuing precertificates")
}
res, err := cac.inner.IssueCertificateForPrecertificate(ctx, req)
if err != nil {
return core.Certificate{}, err
}
return pbToCert(res), nil
}
func (cac CertificateAuthorityClientWrapper) GenerateOCSP(ctx context.Context, ocspReq core.OCSPSigningRequest) ([]byte, error) {
if cac.innerOCSP == nil {
return nil, errors.New("this CA client does not support generating OCSP")
@ -90,6 +101,14 @@ func (cas *CertificateAuthorityServerWrapper) IssuePrecertificate(ctx context.Co
return cas.inner.IssuePrecertificate(ctx, request)
}
func (cas *CertificateAuthorityServerWrapper) IssueCertificateForPrecertificate(ctx context.Context, req *caPB.IssueCertificateForPrecertificateRequest) (*corepb.Certificate, error) {
cert, err := cas.inner.IssueCertificateForPrecertificate(ctx, req)
if err != nil {
return nil, err
}
return certToPB(cert), nil
}
func (cas *CertificateAuthorityServerWrapper) GenerateOCSP(ctx context.Context, request *caPB.GenerateOCSPRequest) (*caPB.OCSPResponse, error) {
res, err := cas.inner.GenerateOCSP(ctx, core.OCSPSigningRequest{
CertDER: request.CertDER,

View File

@ -38,6 +38,11 @@ func (ca *MockCA) IssuePrecertificate(ctx context.Context, _ *caPB.IssueCertific
return nil, fmt.Errorf("MockCA does not implement IssuePrecertificate")
}
// IssueCertificateForPrecertificate is a mock
func (ca *MockCA) IssueCertificateForPrecertificate(ctx context.Context, _ *caPB.IssueCertificateForPrecertificateRequest) (core.Certificate, error) {
return core.Certificate{}, fmt.Errorf("MockCA does not implement IssueCertificateForPrecertificate")
}
// GenerateOCSP is a mock
func (ca *MockCA) GenerateOCSP(ctx context.Context, xferObj core.OCSPSigningRequest) (ocsp []byte, err error) {
return