diff options
Diffstat (limited to 'vendor/github.com/Philipp15b/go-steam/cryptoutil')
4 files changed, 162 insertions, 0 deletions
diff --git a/vendor/github.com/Philipp15b/go-steam/cryptoutil/cryptoutil.go b/vendor/github.com/Philipp15b/go-steam/cryptoutil/cryptoutil.go new file mode 100644 index 00000000..b44f8d26 --- /dev/null +++ b/vendor/github.com/Philipp15b/go-steam/cryptoutil/cryptoutil.go @@ -0,0 +1,38 @@ +package cryptoutil
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+)
+
+// Performs an encryption using AES/CBC/PKCS7
+// with a random IV prepended using AES/ECB/None.
+func SymmetricEncrypt(ciph cipher.Block, src []byte) []byte {
+ // get a random IV and ECB encrypt it
+ iv := make([]byte, aes.BlockSize, aes.BlockSize)
+ _, err := rand.Read(iv)
+ if err != nil {
+ panic(err)
+ }
+ encryptedIv := make([]byte, aes.BlockSize, aes.BlockSize)
+ newECBEncrypter(ciph).CryptBlocks(encryptedIv, iv)
+
+ // pad it, copy the IV to the first 16 bytes and encrypt the rest with CBC
+ encrypted := padPKCS7WithIV(src)
+ copy(encrypted, encryptedIv)
+ cipher.NewCBCEncrypter(ciph, iv).CryptBlocks(encrypted[aes.BlockSize:], encrypted[aes.BlockSize:])
+ return encrypted
+}
+
+// Decrypts data from the reader using AES/CBC/PKCS7 with an IV
+// prepended using AES/ECB/None. The src slice may not be used anymore.
+func SymmetricDecrypt(ciph cipher.Block, src []byte) []byte {
+ iv := src[:aes.BlockSize]
+ newECBDecrypter(ciph).CryptBlocks(iv, iv)
+
+ data := src[aes.BlockSize:]
+ cipher.NewCBCDecrypter(ciph, iv).CryptBlocks(data, data)
+
+ return unpadPKCS7(data)
+}
diff --git a/vendor/github.com/Philipp15b/go-steam/cryptoutil/ecb.go b/vendor/github.com/Philipp15b/go-steam/cryptoutil/ecb.go new file mode 100644 index 00000000..4298686f --- /dev/null +++ b/vendor/github.com/Philipp15b/go-steam/cryptoutil/ecb.go @@ -0,0 +1,68 @@ +package cryptoutil
+
+import (
+ "crypto/cipher"
+)
+
+// From this code review: https://codereview.appspot.com/7860047/
+// by fasmat for the Go crypto/cipher package
+
+type ecb struct {
+ b cipher.Block
+ blockSize int
+}
+
+func newECB(b cipher.Block) *ecb {
+ return &ecb{
+ b: b,
+ blockSize: b.BlockSize(),
+ }
+}
+
+type ecbEncrypter ecb
+
+// NewECBEncrypter returns a BlockMode which encrypts in electronic code book
+// mode, using the given Block.
+func newECBEncrypter(b cipher.Block) cipher.BlockMode {
+ return (*ecbEncrypter)(newECB(b))
+}
+
+func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
+
+func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
+ if len(src)%x.blockSize != 0 {
+ panic("cryptoutil/ecb: input not full blocks")
+ }
+ if len(dst) < len(src) {
+ panic("cryptoutil/ecb: output smaller than input")
+ }
+ for len(src) > 0 {
+ x.b.Encrypt(dst, src[:x.blockSize])
+ src = src[x.blockSize:]
+ dst = dst[x.blockSize:]
+ }
+}
+
+type ecbDecrypter ecb
+
+// newECBDecrypter returns a BlockMode which decrypts in electronic code book
+// mode, using the given Block.
+func newECBDecrypter(b cipher.Block) cipher.BlockMode {
+ return (*ecbDecrypter)(newECB(b))
+}
+
+func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
+
+func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
+ if len(src)%x.blockSize != 0 {
+ panic("cryptoutil/ecb: input not full blocks")
+ }
+ if len(dst) < len(src) {
+ panic("cryptoutil/ecb: output smaller than input")
+ }
+ for len(src) > 0 {
+ x.b.Decrypt(dst, src[:x.blockSize])
+ src = src[x.blockSize:]
+ dst = dst[x.blockSize:]
+ }
+}
diff --git a/vendor/github.com/Philipp15b/go-steam/cryptoutil/pkcs7.go b/vendor/github.com/Philipp15b/go-steam/cryptoutil/pkcs7.go new file mode 100644 index 00000000..8200fb94 --- /dev/null +++ b/vendor/github.com/Philipp15b/go-steam/cryptoutil/pkcs7.go @@ -0,0 +1,25 @@ +package cryptoutil
+
+import (
+ "crypto/aes"
+)
+
+// Returns a new byte array padded with PKCS7 and prepended
+// with empty space of the AES block size (16 bytes) for the IV.
+func padPKCS7WithIV(src []byte) []byte {
+ missing := aes.BlockSize - (len(src) % aes.BlockSize)
+ newSize := len(src) + aes.BlockSize + missing
+ dest := make([]byte, newSize, newSize)
+ copy(dest[aes.BlockSize:], src)
+
+ padding := byte(missing)
+ for i := newSize - missing; i < newSize; i++ {
+ dest[i] = padding
+ }
+ return dest
+}
+
+func unpadPKCS7(src []byte) []byte {
+ padLen := src[len(src)-1]
+ return src[:len(src)-int(padLen)]
+}
diff --git a/vendor/github.com/Philipp15b/go-steam/cryptoutil/rsa.go b/vendor/github.com/Philipp15b/go-steam/cryptoutil/rsa.go new file mode 100644 index 00000000..78cd954a --- /dev/null +++ b/vendor/github.com/Philipp15b/go-steam/cryptoutil/rsa.go @@ -0,0 +1,31 @@ +package cryptoutil
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/x509"
+ "errors"
+)
+
+// Parses a DER encoded RSA public key
+func ParseASN1RSAPublicKey(derBytes []byte) (*rsa.PublicKey, error) {
+ key, err := x509.ParsePKIXPublicKey(derBytes)
+ if err != nil {
+ return nil, err
+ }
+ pubKey, ok := key.(*rsa.PublicKey)
+ if !ok {
+ return nil, errors.New("not an RSA public key")
+ }
+ return pubKey, nil
+}
+
+// Encrypts a message with the given public key using RSA-OAEP and the sha1 hash function.
+func RSAEncrypt(pub *rsa.PublicKey, msg []byte) []byte {
+ b, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, pub, msg, nil)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
|