func (s *Server) handle(conn *gokeyless.Conn) { defer conn.Close() s.Log.Println("Handling new connection...") // Continuosly read request Headers from conn and respond // until a connection error (Read/Write failure) is encountered. var connError error for connError == nil { conn.SetDeadline(time.Now().Add(time.Hour)) var h *gokeyless.Header if h, connError = conn.ReadHeader(); connError != nil { continue } s.Log.Printf("version:%d.%d id:%d body:%s", h.MajorVers, h.MinorVers, h.ID, h.Body) var opts crypto.SignerOpts var isRSA bool var key crypto.Signer var ok bool switch h.Body.Opcode { case gokeyless.OpPing: connError = conn.RespondPong(h.ID, h.Body.Payload) continue case gokeyless.OpRSADecrypt: if key, ok = s.getKey(h.Body.SKI, h.Body.Digest); !ok { s.Log.Println(gokeyless.ErrKeyNotFound) connError = conn.RespondError(h.ID, gokeyless.ErrKeyNotFound) continue } if _, ok = key.Public().(*rsa.PublicKey); !ok { s.Log.Printf("%s: Key is not RSA\n", gokeyless.ErrCrypto) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) continue } rsaKey, ok := key.(crypto.Decrypter) if !ok { s.Log.Printf("%s: Key is not Decrypter\n", gokeyless.ErrCrypto) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) continue } ptxt, err := rsaKey.Decrypt(nil, h.Body.Payload, nil) if err != nil { s.Log.Printf("%s: Decryption error: %v", gokeyless.ErrCrypto, err) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) continue } connError = conn.Respond(h.ID, ptxt) continue case gokeyless.OpRSASignMD5SHA1: isRSA = true fallthrough case gokeyless.OpECDSASignMD5SHA1: opts = crypto.MD5SHA1 case gokeyless.OpRSASignSHA1: isRSA = true fallthrough case gokeyless.OpECDSASignSHA1: opts = crypto.SHA1 case gokeyless.OpRSASignSHA224: case gokeyless.OpECDSASignSHA224: opts = crypto.SHA224 case gokeyless.OpRSASignSHA256: isRSA = true fallthrough case gokeyless.OpECDSASignSHA256: opts = crypto.SHA256 case gokeyless.OpRSASignSHA384: isRSA = true fallthrough case gokeyless.OpECDSASignSHA384: opts = crypto.SHA384 case gokeyless.OpRSASignSHA512: isRSA = true fallthrough case gokeyless.OpECDSASignSHA512: opts = crypto.SHA512 case gokeyless.OpPong: fallthrough case gokeyless.OpResponse: fallthrough case gokeyless.OpError: s.Log.Printf("%s: %s is not a valid request Opcode\n", gokeyless.ErrUnexpectedOpcode, h.Body.Opcode) connError = conn.RespondError(h.ID, gokeyless.ErrUnexpectedOpcode) continue default: connError = conn.RespondError(h.ID, gokeyless.ErrBadOpcode) continue } if key, ok = s.getKey(h.Body.SKI, h.Body.Digest); !ok { s.Log.Println(gokeyless.ErrKeyNotFound) connError = conn.RespondError(h.ID, gokeyless.ErrKeyNotFound) continue } // Ensure we don't perform an ECDSA sign for an RSA request. if _, ok := key.Public().(*rsa.PublicKey); isRSA && !ok { s.Log.Printf("%s: request is RSA, but key is ECDSA\n", gokeyless.ErrCrypto) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) continue } sig, err := key.Sign(rand.Reader, h.Body.Payload, opts) if err != nil { s.Log.Printf("%s: Signing error: %v\n", gokeyless.ErrCrypto, err) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) continue } connError = conn.Respond(h.ID, sig) } s.Log.Printf("Connection error: %v\n", connError) return }
func (s *Server) handle(conn *gokeyless.Conn) { defer conn.Close() log.Debug("Handling new connection...") // Continuosly read request Headers from conn and respond // until a connection error (Read/Write failure) is encountered. var connError error for connError == nil { conn.SetDeadline(time.Now().Add(time.Hour)) var h *gokeyless.Header if h, connError = conn.ReadHeader(); connError != nil { continue } requestBegin := time.Now() log.Debugf("version:%d.%d id:%d body:%s", h.MajorVers, h.MinorVers, h.ID, h.Body) var opts crypto.SignerOpts var key crypto.Signer var ok bool switch h.Body.Opcode { case gokeyless.OpPing: connError = conn.RespondPong(h.ID, h.Body.Payload) s.stats.logRequest(requestBegin) continue case gokeyless.OpRSADecrypt: if key, ok = s.Keys.Get(h.Body); !ok { log.Error(gokeyless.ErrKeyNotFound) connError = conn.RespondError(h.ID, gokeyless.ErrKeyNotFound) s.stats.logInvalid(requestBegin) continue } if _, ok = key.Public().(*rsa.PublicKey); !ok { log.Errorf("%s: Key is not RSA\n", gokeyless.ErrCrypto) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) s.stats.logInvalid(requestBegin) continue } rsaKey, ok := key.(crypto.Decrypter) if !ok { log.Errorf("%s: Key is not Decrypter\n", gokeyless.ErrCrypto) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) s.stats.logInvalid(requestBegin) continue } ptxt, err := rsaKey.Decrypt(nil, h.Body.Payload, nil) if err != nil { log.Errorf("%s: Decryption error: %v", gokeyless.ErrCrypto, err) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) s.stats.logInvalid(requestBegin) continue } connError = conn.Respond(h.ID, ptxt) s.stats.logRequest(requestBegin) continue case gokeyless.OpRSASignMD5SHA1, gokeyless.OpECDSASignMD5SHA1: opts = crypto.MD5SHA1 case gokeyless.OpRSASignSHA1, gokeyless.OpECDSASignSHA1: opts = crypto.SHA1 case gokeyless.OpRSASignSHA224, gokeyless.OpECDSASignSHA224: opts = crypto.SHA224 case gokeyless.OpRSASignSHA256, gokeyless.OpECDSASignSHA256: opts = crypto.SHA256 case gokeyless.OpRSASignSHA384, gokeyless.OpECDSASignSHA384: opts = crypto.SHA384 case gokeyless.OpRSASignSHA512, gokeyless.OpECDSASignSHA512: opts = crypto.SHA512 case gokeyless.OpActivate: if len(s.ActivationToken) > 0 { hashedToken := sha256.Sum256(s.ActivationToken) connError = conn.Respond(h.ID, hashedToken[:]) s.stats.logRequest(requestBegin) } else { connError = conn.RespondError(h.ID, gokeyless.ErrBadOpcode) s.stats.logInvalid(requestBegin) } continue case gokeyless.OpPong, gokeyless.OpResponse, gokeyless.OpError: log.Errorf("%s: %s is not a valid request Opcode\n", gokeyless.ErrUnexpectedOpcode, h.Body.Opcode) connError = conn.RespondError(h.ID, gokeyless.ErrUnexpectedOpcode) s.stats.logInvalid(requestBegin) continue default: connError = conn.RespondError(h.ID, gokeyless.ErrBadOpcode) s.stats.logInvalid(requestBegin) continue } if key, ok = s.Keys.Get(h.Body); !ok { log.Error(gokeyless.ErrKeyNotFound) connError = conn.RespondError(h.ID, gokeyless.ErrKeyNotFound) s.stats.logInvalid(requestBegin) continue } // Ensure we don't perform an ECDSA sign for an RSA request. switch h.Body.Opcode { case gokeyless.OpRSASignMD5SHA1, gokeyless.OpRSASignSHA1, gokeyless.OpRSASignSHA224, gokeyless.OpRSASignSHA256, gokeyless.OpRSASignSHA384, gokeyless.OpRSASignSHA512: if _, ok := key.Public().(*rsa.PublicKey); !ok { log.Errorf("%s: request is RSA, but key isn't\n", gokeyless.ErrCrypto) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) s.stats.logInvalid(requestBegin) continue } } sig, err := key.Sign(rand.Reader, h.Body.Payload, opts) if err != nil { log.Errorf("%s: Signing error: %v\n", gokeyless.ErrCrypto, err) connError = conn.RespondError(h.ID, gokeyless.ErrCrypto) s.stats.logInvalid(requestBegin) continue } connError = conn.Respond(h.ID, sig) s.stats.logRequest(requestBegin) } if connError == io.EOF { log.Debug("connection closed by client") } else { log.Errorf("connection error: %v\n", connError) } }