Fix crypto
This commit is contained in:
parent
da4224ba23
commit
02e6457443
3 changed files with 154 additions and 113 deletions
117
crypto.go
Normal file
117
crypto.go
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
cipher2 "crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"golang.org/x/crypto/blowfish"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BaseMessage struct {
|
||||||
|
Signature string
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecryptAndVerify(input []byte, key *rsa.PrivateKey, pub *rsa.PublicKey, signature []byte, v interface{}) error {
|
||||||
|
all, err := hex.DecodeString(string(input))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
encPasswordAndIV := all[:512]
|
||||||
|
encBody := all[512:]
|
||||||
|
|
||||||
|
passwordAndIV, err := rsa.DecryptPKCS1v15(rand.Reader, key, encPasswordAndIV)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
password := passwordAndIV[:32]
|
||||||
|
iv := passwordAndIV[32:]
|
||||||
|
|
||||||
|
cipher, err := blowfish.NewCipher(password)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
body := make([]byte, len(encBody))
|
||||||
|
dec := cipher2.NewCBCDecrypter(cipher, iv)
|
||||||
|
dec.CryptBlocks(body, encBody)
|
||||||
|
err = json.Unmarshal(body, v)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
baseReq, ok := v.(*BaseMessage)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("non-base request")
|
||||||
|
}
|
||||||
|
|
||||||
|
recvSignature, err := hex.DecodeString(baseReq.Signature)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fingerprint := signature
|
||||||
|
fingerprintHashed := sha256.Sum256(fingerprint)
|
||||||
|
err = rsa.VerifyPKCS1v15(pub, 0, fingerprintHashed[:], recvSignature)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncryptAndSign(v interface{}, key *rsa.PrivateKey, pub *rsa.PublicKey, signature []byte, writer io.Writer) error {
|
||||||
|
passwordAndIV := make([]byte, 40)
|
||||||
|
_, err := rand.Read(passwordAndIV)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
encPasswordAndIV, err := rsa.EncryptPKCS1v15(rand.Reader, pub, passwordAndIV)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = writer.Write([]byte(hex.EncodeToString(encPasswordAndIV)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
password := passwordAndIV[:32]
|
||||||
|
iv := passwordAndIV[32:]
|
||||||
|
|
||||||
|
cipher, err := blowfish.NewCipher(password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hashedFingerpint := sha256.Sum256(signature)
|
||||||
|
plainSignature, err := rsa.SignPKCS1v15(rand.Reader, key, 0, hashedFingerpint[:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sign, ok := v.(*BaseMessage)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("given message can't be signed")
|
||||||
|
}
|
||||||
|
sign.Signature = hex.EncodeToString(plainSignature)
|
||||||
|
|
||||||
|
body, err := json.Marshal(v)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
encBody := make([]byte, len(body))
|
||||||
|
enc := cipher2.NewCBCEncrypter(cipher, iv)
|
||||||
|
enc.CryptBlocks(encBody, body)
|
||||||
|
writer.Write([]byte(hex.EncodeToString(encBody)))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
29
crypto_test.go
Normal file
29
crypto_test.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package service_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"git.cijber.net/zer.ooo/service"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSingleRound(t *testing.T) {
|
||||||
|
keyA, _ := rsa.GenerateKey(rand.Reader, 4096)
|
||||||
|
keyB, _ := rsa.GenerateKey(rand.Reader, 4096)
|
||||||
|
signature := []byte("Hello world!")
|
||||||
|
v := &service.BaseMessage{}
|
||||||
|
x := make([]byte, 0)
|
||||||
|
b := bytes.NewBuffer(x)
|
||||||
|
err := service.EncryptAndSign(v, keyA, &keyB.PublicKey, signature, b)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed encrypting: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = service.DecryptAndVerify(b.Bytes(), keyB, &keyA.PublicKey, signature, &service.BaseMessage{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed decrypting: %s", err)
|
||||||
|
}
|
||||||
|
}
|
121
http.go
121
http.go
|
@ -1,20 +1,12 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
import "golang.org/x/crypto/blowfish"
|
|
||||||
|
|
||||||
type Status int
|
type Status int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -23,11 +15,7 @@ const (
|
||||||
ERROR
|
ERROR
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseMessage struct {
|
type HttpServer struct {
|
||||||
Signature string
|
|
||||||
}
|
|
||||||
|
|
||||||
type httpServer struct {
|
|
||||||
manager *Manager
|
manager *Manager
|
||||||
status Status
|
status Status
|
||||||
}
|
}
|
||||||
|
@ -52,11 +40,11 @@ type DeliverCertificateRequest struct {
|
||||||
Certificate string
|
Certificate string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpServer(manager *Manager) *httpServer {
|
func NewHttpServer(manager *Manager) *HttpServer {
|
||||||
return &httpServer{manager, WAITING}
|
return &HttpServer{manager, WAITING}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *httpServer) Start() {
|
func (it *HttpServer) Start() {
|
||||||
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
|
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
|
||||||
log.Printf("%s /", strings.ToUpper(request.Method))
|
log.Printf("%s /", strings.ToUpper(request.Method))
|
||||||
writer.WriteHeader(200)
|
writer.WriteHeader(200)
|
||||||
|
@ -126,108 +114,15 @@ func (it *httpServer) Start() {
|
||||||
http.ListenAndServe(":7864", nil)
|
http.ListenAndServe(":7864", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *httpServer) writeResponse(writer http.ResponseWriter, v interface{}) error {
|
func (it *HttpServer) writeResponse(writer http.ResponseWriter, v interface{}) error {
|
||||||
passwordAndIV := make([]byte, 48)
|
return EncryptAndSign(v, it.manager.privateKey, it.manager.CAPublicKey(), it.manager.GetServerFingerprint(), writer)
|
||||||
_, err := rand.Read(passwordAndIV)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encPasswordAndIV, err := rsa.EncryptPKCS1v15(rand.Reader, it.manager.CAPublicKey(), passwordAndIV)
|
func (it *HttpServer) verifyRequest(r *http.Request, v interface{}) (error) {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = writer.Write([]byte(hex.EncodeToString(encPasswordAndIV)))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
password := passwordAndIV[:32]
|
|
||||||
iv := passwordAndIV[32:]
|
|
||||||
|
|
||||||
cipher, err := blowfish.NewSaltedCipher(password, iv)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
hashedFingerpint := sha256.Sum256(it.manager.GetServerFingerprint())
|
|
||||||
plainSignature, err := rsa.SignPKCS1v15(rand.Reader, it.manager.privateKey, 0, hashedFingerpint[:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
sign, ok := v.(*BaseMessage)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("Given message can't be signed")
|
|
||||||
}
|
|
||||||
sign.Signature = hex.EncodeToString(plainSignature)
|
|
||||||
|
|
||||||
body, err := json.Marshal(v)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
encBody := make([]byte, len(body))
|
|
||||||
cipher.Encrypt(encBody, body)
|
|
||||||
writer.Write([]byte(hex.EncodeToString(encBody)))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *httpServer) verifyRequest(r *http.Request, v interface{}) (error) {
|
|
||||||
hexBody, err := ioutil.ReadAll(r.Body)
|
hexBody, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
all, err := hex.DecodeString(string(hexBody))
|
return DecryptAndVerify(hexBody, it.manager.privateKey, it.manager.CAPublicKey(), it.manager.GetServerFingerprint(), v)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("req: %s", hexBody)
|
|
||||||
|
|
||||||
encPasswordAndIV := all[:256]
|
|
||||||
encBody := all[256:]
|
|
||||||
|
|
||||||
passwordAndIV, err := rsa.DecryptPKCS1v15(rand.Reader, it.manager.privateKey, encPasswordAndIV)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
password := passwordAndIV[:32]
|
|
||||||
iv := passwordAndIV[32:]
|
|
||||||
|
|
||||||
cipher, err := blowfish.NewSaltedCipher(password, iv)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
body := make([]byte, len(encBody))
|
|
||||||
cipher.Decrypt(body, encBody)
|
|
||||||
|
|
||||||
err = json.Unmarshal(body, v)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
baseReq, ok := v.(*BaseMessage)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("non-base request")
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := hex.DecodeString(baseReq.Signature)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fingerprint := it.manager.GetServerFingerprint()
|
|
||||||
fingerprintHashed := sha256.Sum256(fingerprint)
|
|
||||||
err = rsa.VerifyPKCS1v15(it.manager.CAPublicKey(), 0, fingerprintHashed[:], signature)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue