diff --git a/internal/server/server.go b/internal/server/server.go index 3361623..5f8ccf1 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -217,6 +217,8 @@ func (s *Server) handleStream(ctx context.Context, stream *quic.Stream, sess *Se s.handleReroll(sess) case types.OpAuthCert: s.handleAuthCert(sess, frame.Payload) + case types.OpRegister: + s.handleRegister(sess, frame.Payload) case types.OpDial: if !sess.IsAuthenticated() { sendOpError(st, types.ErrInvalidRequest, "not authenticated") @@ -367,6 +369,45 @@ func (s *Server) handleAuthCert(sess *Session, payload []byte) { zap.String("number", ident.Number)) } +func (s *Server) handleRegister(sess *Session, payload []byte) { + if len(payload) < 32 { + sendOpError(sess.Stream(), types.ErrInvalidRequest, "invalid pubkey") + return + } + + var pubKey [32]byte + copy(pubKey[:], payload[:32]) + + if _, err := s.identMgr.GetByPubKey(pubKey); err == nil { + sendOpError(sess.Stream(), types.ErrInvalidRequest, "already registered") + return + } + + ident, err := s.identMgr.Allocate(pubKey) + if err != nil { + sendOpError(sess.Stream(), types.ErrInternal, err.Error()) + return + } + + certDER, err := s.ca.IssueCert(ident.Number, ed25519.PublicKey(pubKey[:]), s.cfg.CA.Validity) + if err != nil { + sendOpError(sess.Stream(), types.ErrInternal, "cert issuance failed") + return + } + ident.CertDER = certDER + + sess.Authenticate(ident.Number, pubKey, certDER) + s.Register(sess, ident.Number) + + payload = marshalIdentityResponse(ident.Number, certDER, s.ca.CACertPEM()) + if st := sess.Stream(); st != nil { + st.WriteFrame(byte(types.OpIdentity), payload) + } + + s.logger.Info("Client registered", + zap.String("number", ident.Number)) +} + func (s *Server) handleReroll(sess *Session) { if !sess.IsAuthenticated() { sendOpError(sess.Stream(), types.ErrInvalidRequest, "not authenticated") diff --git a/pkg/types/opcode.go b/pkg/types/opcode.go index 144df9f..97c5855 100644 --- a/pkg/types/opcode.go +++ b/pkg/types/opcode.go @@ -9,6 +9,7 @@ const ( OpIdentity OpCode = 0x04 OpReroll OpCode = 0x05 OpAuthCert OpCode = 0x06 + OpRegister OpCode = 0x07 OpDial OpCode = 0x10 OpRing OpCode = 0x11