Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions cmd/boulder-mtca/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package notmain

import (
"context"
"flag"
"os"

"github.com/jmhodges/clock"

"github.com/letsencrypt/boulder/cmd"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/issuance"
mtca "github.com/letsencrypt/boulder/mtca"
mtcapb "github.com/letsencrypt/boulder/mtca/proto"
)

type Config struct {
MTCA struct {
cmd.ServiceConfig

GRPCMTCA *cmd.GRPCServerConfig

// Issuer holds the configuration for a single MTCA instance with a single mtcaID.
// We run a separate process for each issuer.
// TODO: the issuance package parses the CA certificate as a self-signed X.509
// certificate, but per MTC draft, a CA SHOULD be represented by an RFC 9925
// unsigned certificate: https://www.rfc-editor.org/rfc/rfc9925.html.
Issuer issuance.IssuerConfig
}

Syslog cmd.SyslogConfig
OpenTelemetry cmd.OpenTelemetryConfig
}

func main() {
grpcAddr := flag.String("addr", "", "gRPC listen address override")
debugAddr := flag.String("debug-addr", "", "Debug server address override")
configFile := flag.String("config", "", "File path to the configuration file for this service")
flag.Parse()
if *configFile == "" {
flag.Usage()
os.Exit(1)
}

var c Config
err := cmd.ReadConfigFile(*configFile, &c)
cmd.FailOnError(err, "Reading JSON config file into config structure")

if *grpcAddr != "" {
c.MTCA.GRPCMTCA.Address = *grpcAddr
}
if *debugAddr != "" {
c.MTCA.DebugAddr = *debugAddr
}

scope, logger, oTelShutdown := cmd.StatsAndLogging(c.Syslog, c.OpenTelemetry, c.MTCA.DebugAddr)
defer oTelShutdown(context.Background())
cmd.LogStartup(logger)

tlsConfig, err := c.MTCA.TLS.Load(scope)
cmd.FailOnError(err, "Loading TLS config")

clk := clock.New()

issuer, err := issuance.LoadIssuer(c.MTCA.Issuer, clk)
cmd.FailOnError(err, "Loading issuer")

mtcaImpl := mtca.New(issuer)

srv := bgrpc.NewServer(c.MTCA.GRPCMTCA, logger).Add(
&mtcapb.MTCA_ServiceDesc, mtcaImpl)

start, err := srv.Build(tlsConfig, scope, clk)
cmd.FailOnError(err, "Unable to setup MTCA gRPC server")

cmd.FailOnError(start(), "MTCA gRPC service failed")
}

func init() {
cmd.RegisterCommand("boulder-mtca", main, &cmd.ConfigValidator{Config: &Config{}})
}
1 change: 1 addition & 0 deletions cmd/boulder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

_ "github.com/letsencrypt/boulder/cmd/bad-key-revoker"
_ "github.com/letsencrypt/boulder/cmd/boulder-ca"
_ "github.com/letsencrypt/boulder/cmd/boulder-mtca"
_ "github.com/letsencrypt/boulder/cmd/boulder-observer"
_ "github.com/letsencrypt/boulder/cmd/boulder-publisher"
_ "github.com/letsencrypt/boulder/cmd/boulder-ra"
Expand Down
2 changes: 2 additions & 0 deletions cmd/boulder/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ func TestConfigValidation(t *testing.T) {
switch cmdName {
case "boulder-ca":
fileNames = []string{"ca.json"}
case "boulder-mtca":
fileNames = []string{"mtca.json"}
case "boulder-observer":
fileNames = []string{"observer.yml"}
case "boulder-publisher":
Expand Down
26 changes: 26 additions & 0 deletions mtca/mtca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package mtca

import (
"context"
"fmt"

"github.com/letsencrypt/boulder/issuance"
mtcapb "github.com/letsencrypt/boulder/mtca/proto"
)

var _ mtcapb.MTCAServer = &mtca{}

func New(issuer *issuance.Issuer) *mtca {
return &mtca{
issuer: issuer,
}
}

type mtca struct {
mtcapb.UnimplementedMTCAServer
issuer *issuance.Issuer
}

func (m *mtca) Issue(ctx context.Context, req *mtcapb.IssueRequest) (*mtcapb.IssueResponse, error) {
return nil, fmt.Errorf("not implemented")
}
218 changes: 218 additions & 0 deletions mtca/proto/mtca.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions mtca/proto/mtca.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
syntax = "proto3";

package mtca;
option go_package = "github.com/letsencrypt/boulder/mtca/proto";

import "core/proto/core.proto";

// MTCA issues MTC certificates.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"ATM machine"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is the future to which we are doomed. MT certificates feels wrong; "issues MTCs" is also ugly IMO. I think the path is to just make peace with saying ATM machine for the rest of our lives.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, "issues MTCs" doesn't sound bad to me personally. I'd also be fine with it just saying "issues Merkle Tree Certificates", given that this is sorta the entry-point into documentation for this package.

But also none of this matters, the point of language is to communicate and the current version is clear.

service MTCA {
// Issue requests that the CA start the process of creating a standalone certificate
// for the given request. It returns once a checkpoint has been signed that includes
// that certificate's TBSCertificateLogEntry, but does not wait for cosignatures.
rpc Issue(IssueRequest) returns (IssueResponse) {}
}

message IssueRequest {
// Next unused field number: 4
bytes pubkey = 1;
repeated core.Identifier identifiers = 2;
string profile = 3;
}
Comment thread
aarongable marked this conversation as resolved.

message IssueResponse {
// Next unused field number: 4
string mtcLogID = 1;
int64 mtcEntryIndex = 2;
}
Loading