示例#1
0
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
}
示例#2
0
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)
	}
}