Fix crypto

master
eater 5 years ago
parent da4224ba23
commit 02e6457443
Signed by: eater
GPG Key ID: 656785D50BE51C0A

@ -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
}

@ -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)
}
}

@ -1,20 +1,12 @@
package service
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"io/ioutil"
"log"
"net/http"
"strings"
)
import "golang.org/x/crypto/blowfish"
type Status int
const (
@ -23,11 +15,7 @@ const (
ERROR
)
type BaseMessage struct {
Signature string
}
type httpServer struct {
type HttpServer struct {
manager *Manager
status Status
}
@ -52,11 +40,11 @@ type DeliverCertificateRequest struct {
Certificate string
}
func NewHttpServer(manager *Manager) *httpServer {
return &httpServer{manager, WAITING}
func NewHttpServer(manager *Manager) *HttpServer {
return &HttpServer{manager, WAITING}
}
func (it *httpServer) Start() {
func (it *HttpServer) Start() {
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
log.Printf("%s /", strings.ToUpper(request.Method))
writer.WriteHeader(200)
@ -126,108 +114,15 @@ func (it *httpServer) Start() {
http.ListenAndServe(":7864", nil)
}
func (it *httpServer) writeResponse(writer http.ResponseWriter, v interface{}) error {
passwordAndIV := make([]byte, 48)
_, err := rand.Read(passwordAndIV)
if err != nil {
return err
}
encPasswordAndIV, err := rsa.EncryptPKCS1v15(rand.Reader, it.manager.CAPublicKey(), 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.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) writeResponse(writer http.ResponseWriter, v interface{}) error {
return EncryptAndSign(v, it.manager.privateKey, it.manager.CAPublicKey(), it.manager.GetServerFingerprint(), writer)
}
func (it *httpServer) verifyRequest(r *http.Request, v interface{}) (error) {
func (it *HttpServer) verifyRequest(r *http.Request, v interface{}) (error) {
hexBody, err := ioutil.ReadAll(r.Body)
if err != nil {
return err
}
all, err := hex.DecodeString(string(hexBody))
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
return DecryptAndVerify(hexBody, it.manager.privateKey, it.manager.CAPublicKey(), it.manager.GetServerFingerprint(), v)
}

Loading…
Cancel
Save