Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-dms3
Commits
c6823ac6
Commit
c6823ac6
authored
10 years ago
by
Brendan Mc
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleaned up code some.
parent
80ec51f1
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
219 additions
and
261 deletions
+219
-261
crypto/key.go
crypto/key.go
+149
-6
crypto/rsa.go
crypto/rsa.go
+0
-8
identify/identify.go
identify/identify.go
+70
-247
No files found.
crypto/key.go
View file @
c6823ac6
package
crypto
import
(
"bytes"
"errors"
"crypto/elliptic"
"crypto/hmac"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"hash"
"math/big"
"code.google.com/p/goprotobuf/proto"
)
...
...
@@ -19,9 +27,6 @@ type PrivKey interface {
// Cryptographically sign the given bytes
Sign
([]
byte
)
([]
byte
,
error
)
// Decrypt a message encrypted with this keys public key
Decrypt
([]
byte
)
([]
byte
,
error
)
// Return a public key paired with this private key
GetPublic
()
PubKey
...
...
@@ -36,13 +41,13 @@ type PubKey interface {
// Verify that 'sig' is the signed hash of 'data'
Verify
(
data
[]
byte
,
sig
[]
byte
)
(
bool
,
error
)
// Encrypt the given data with the public key
Encrypt
([]
byte
)
([]
byte
,
error
)
// Bytes returns a serialized, storeable representation of this key
Bytes
()
([]
byte
,
error
)
}
// Given a public key, generates the shared key.
type
GenSharedKey
func
([]
byte
)
([]
byte
,
error
)
func
GenerateKeyPair
(
typ
,
bits
int
)
(
PrivKey
,
PubKey
,
error
)
{
switch
typ
{
case
RSA
:
...
...
@@ -57,6 +62,144 @@ func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
}
}
// Generates an ephemeral public key and returns a function that will compute
// the shared secret key. Used in the identify module.
//
// Focuses only on ECDH now, but can be made more general in the future.
func
GenerateEKeyPair
(
curveName
string
)
([]
byte
,
GenSharedKey
,
error
)
{
var
curve
elliptic
.
Curve
switch
curveName
{
case
"P-224"
:
curve
=
elliptic
.
P224
()
case
"P-256"
:
curve
=
elliptic
.
P256
()
case
"P-384"
:
curve
=
elliptic
.
P384
()
case
"P-521"
:
curve
=
elliptic
.
P521
()
}
priv
,
x
,
y
,
err
:=
elliptic
.
GenerateKey
(
curve
,
rand
.
Reader
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
var
pubKey
bytes
.
Buffer
pubKey
.
Write
(
x
.
Bytes
())
pubKey
.
Write
(
y
.
Bytes
())
done
:=
func
(
theirPub
[]
byte
)
([]
byte
,
error
)
{
// Verify and unpack node's public key.
curveSize
:=
curve
.
Params
()
.
BitSize
if
len
(
theirPub
)
!=
(
curveSize
/
4
)
{
return
nil
,
errors
.
New
(
"Malformed public key."
)
}
bound
:=
(
curveSize
/
8
)
x
:=
big
.
NewInt
(
0
)
y
:=
big
.
NewInt
(
0
)
x
.
SetBytes
(
theirPub
[
0
:
bound
])
y
.
SetBytes
(
theirPub
[
bound
:
bound
*
2
])
if
!
curve
.
IsOnCurve
(
x
,
y
)
{
return
nil
,
errors
.
New
(
"Invalid public key."
)
}
// Generate shared secret.
secret
,
_
:=
curve
.
ScalarMult
(
x
,
y
,
priv
)
return
secret
.
Bytes
(),
nil
}
return
pubKey
.
Bytes
(),
done
,
nil
}
// Generates a set of keys for each party by stretching the shared key.
// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey)
func
KeyStretcher
(
cmp
int
,
cipherType
string
,
hashType
string
,
secret
[]
byte
)
([]
byte
,
[]
byte
,
[]
byte
,
[]
byte
,
[]
byte
,
[]
byte
)
{
var
cipherKeySize
int
switch
cipherType
{
case
"AES-128"
:
cipherKeySize
=
16
case
"AES-256"
:
cipherKeySize
=
32
}
ivSize
:=
16
hmacKeySize
:=
20
seed
:=
[]
byte
(
"key expansion"
)
result
:=
make
([]
byte
,
2
*
(
ivSize
+
cipherKeySize
+
hmacKeySize
))
var
h
func
()
hash
.
Hash
switch
hashType
{
case
"SHA1"
:
h
=
sha1
.
New
case
"SHA256"
:
h
=
sha256
.
New
case
"SHA512"
:
h
=
sha512
.
New
}
m
:=
hmac
.
New
(
h
,
secret
)
m
.
Write
(
seed
)
a
:=
m
.
Sum
(
nil
)
j
:=
0
for
j
<
len
(
result
)
{
m
.
Reset
()
m
.
Write
(
a
)
m
.
Write
(
seed
)
b
:=
m
.
Sum
(
nil
)
todo
:=
len
(
b
)
if
j
+
todo
>
len
(
result
)
{
todo
=
len
(
result
)
-
j
}
copy
(
result
[
j
:
j
+
todo
],
b
)
j
+=
todo
m
.
Reset
()
m
.
Write
(
a
)
a
=
m
.
Sum
(
nil
)
}
myResult
:=
make
([]
byte
,
ivSize
+
cipherKeySize
+
hmacKeySize
)
theirResult
:=
make
([]
byte
,
ivSize
+
cipherKeySize
+
hmacKeySize
)
half
:=
len
(
result
)
/
2
if
cmp
==
1
{
copy
(
myResult
,
result
[
:
half
])
copy
(
theirResult
,
result
[
half
:
])
}
else
if
cmp
==
-
1
{
copy
(
myResult
,
result
[
half
:
])
copy
(
theirResult
,
result
[
:
half
])
}
else
{
// Shouldn't happen, but oh well.
copy
(
myResult
,
result
[
half
:
])
copy
(
theirResult
,
result
[
half
:
])
}
myIV
:=
myResult
[
0
:
ivSize
]
myCKey
:=
myResult
[
ivSize
:
ivSize
+
cipherKeySize
]
myMKey
:=
myResult
[
ivSize
+
cipherKeySize
:
]
theirIV
:=
theirResult
[
0
:
ivSize
]
theirCKey
:=
theirResult
[
ivSize
:
ivSize
+
cipherKeySize
]
theirMKey
:=
theirResult
[
ivSize
+
cipherKeySize
:
]
return
myIV
,
theirIV
,
myCKey
,
theirCKey
,
myMKey
,
theirMKey
}
func
UnmarshalPublicKey
(
data
[]
byte
)
(
PubKey
,
error
)
{
pmes
:=
new
(
PBPublicKey
)
err
:=
proto
.
Unmarshal
(
data
,
pmes
)
...
...
This diff is collapsed.
Click to expand it.
crypto/rsa.go
View file @
c6823ac6
...
...
@@ -28,10 +28,6 @@ func (pk *RsaPublicKey) Verify(data, sig []byte) (bool, error) {
return
true
,
nil
}
func
(
pk
*
RsaPublicKey
)
Encrypt
(
message
[]
byte
)
([]
byte
,
error
)
{
return
rsa
.
EncryptPKCS1v15
(
rand
.
Reader
,
pk
.
k
,
message
)
}
func
(
pk
*
RsaPublicKey
)
Bytes
()
([]
byte
,
error
)
{
b
,
err
:=
x509
.
MarshalPKIXPublicKey
(
pk
.
k
)
if
err
!=
nil
{
...
...
@@ -56,10 +52,6 @@ func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) {
return
rsa
.
SignPKCS1v15
(
rand
.
Reader
,
sk
.
k
,
crypto
.
SHA256
,
hashed
[
:
])
}
func
(
sk
*
RsaPrivateKey
)
Decrypt
(
ciphertext
[]
byte
)
([]
byte
,
error
)
{
return
rsa
.
DecryptPKCS1v15
(
rand
.
Reader
,
sk
.
k
,
ciphertext
)
}
func
(
sk
*
RsaPrivateKey
)
GetPublic
()
PubKey
{
return
&
RsaPublicKey
{
&
sk
.
k
.
PublicKey
}
}
...
...
This diff is collapsed.
Click to expand it.
identify/identify.go
View file @
c6823ac6
...
...
@@ -4,18 +4,17 @@ package identify
import
(
"bytes"
"errors"
"strings"
"crypto/aes"
"crypto/cipher"
"crypto/elliptic"
"crypto/hmac"
"crypto/rand"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"errors"
"hash"
"math/big"
"strings"
proto
"code.google.com/p/goprotobuf/proto"
ci
"github.com/jbenet/go-ipfs/crypto"
...
...
@@ -95,7 +94,7 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) (chan []byte, chan
return
nil
,
nil
,
err
}
epubkey
,
done
,
err
:=
g
enerateE
Pub
Key
(
exchange
)
// Generate EphemeralPubKey
epubkey
,
done
,
err
:=
ci
.
G
enerateEKey
Pair
(
exchange
)
// Generate EphemeralPubKey
var
handshake
bytes
.
Buffer
// Gather corpus to sign.
handshake
.
Write
(
encoded
)
...
...
@@ -144,87 +143,13 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) (chan []byte, chan
}
cmp
:=
bytes
.
Compare
(
myPubKey
,
helloResp
.
GetPubkey
())
mIV
,
tIV
,
mCKey
,
tCKey
,
mMKey
,
tMKey
:=
keyGenerato
r
(
cmp
,
cipherType
,
hashType
,
secret
)
mIV
,
tIV
,
mCKey
,
tCKey
,
mMKey
,
tMKey
:=
ci
.
KeyStretche
r
(
cmp
,
cipherType
,
hashType
,
secret
)
secureIn
:=
make
(
chan
[]
byte
)
secureOut
:=
make
(
chan
[]
byte
)
go
func
()
{
myBlock
,
_
:=
aes
.
NewCipher
(
mCKey
)
myCipher
:=
cipher
.
NewCTR
(
myBlock
,
mIV
)
theirBlock
,
_
:=
aes
.
NewCipher
(
tCKey
)
theirCipher
:=
cipher
.
NewCTR
(
theirBlock
,
tIV
)
var
myMac
,
theirMac
hash
.
Hash
var
macSize
int
switch
hashType
{
case
"SHA1"
:
myMac
=
hmac
.
New
(
sha1
.
New
,
mMKey
)
theirMac
=
hmac
.
New
(
sha1
.
New
,
tMKey
)
macSize
=
20
case
"SHA256"
:
myMac
=
hmac
.
New
(
sha256
.
New
,
mMKey
)
theirMac
=
hmac
.
New
(
sha256
.
New
,
tMKey
)
macSize
=
32
case
"SHA512"
:
myMac
=
hmac
.
New
(
sha512
.
New
,
mMKey
)
theirMac
=
hmac
.
New
(
sha512
.
New
,
tMKey
)
macSize
=
64
}
for
{
select
{
case
data
,
ok
:=
<-
secureOut
:
if
!
ok
{
return
}
if
len
(
data
)
==
0
{
continue
}
buff
:=
make
([]
byte
,
len
(
data
)
+
macSize
)
myCipher
.
XORKeyStream
(
buff
,
data
)
myMac
.
Write
(
buff
[
0
:
len
(
data
)])
copy
(
buff
[
len
(
data
)
:
],
myMac
.
Sum
(
nil
))
myMac
.
Reset
()
out
<-
buff
case
data
,
ok
:=
<-
in
:
if
!
ok
{
return
}
if
len
(
data
)
<=
macSize
{
continue
}
mark
:=
len
(
data
)
-
macSize
buff
:=
make
([]
byte
,
mark
)
theirCipher
.
XORKeyStream
(
buff
,
data
[
0
:
mark
])
theirMac
.
Write
(
data
[
0
:
mark
])
expected
:=
theirMac
.
Sum
(
nil
)
theirMac
.
Reset
()
hmacOk
:=
hmac
.
Equal
(
data
[
mark
:
],
expected
)
if
hmacOk
{
secureIn
<-
buff
}
else
{
secureIn
<-
nil
}
}
}
}()
go
secureInProxy
(
in
,
secureIn
,
hashType
,
tIV
,
tCKey
,
tMKey
)
go
secureOutProxy
(
out
,
secureOut
,
hashType
,
mIV
,
mCKey
,
mMKey
)
finished
:=
[]
byte
(
"Finished"
)
...
...
@@ -240,99 +165,90 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) (chan []byte, chan
return
secureIn
,
secureOut
,
nil
}
func
IdFromPubKey
(
pk
ci
.
PubKey
)
(
peer
.
ID
,
error
)
{
b
,
err
:=
pk
.
Bytes
()
if
err
!=
nil
{
return
nil
,
err
}
hash
,
err
:=
u
.
Hash
(
b
)
if
err
!=
nil
{
return
nil
,
err
func
makeMac
(
hashType
string
,
key
[]
byte
)
(
hash
.
Hash
,
int
)
{
switch
hashType
{
case
"SHA1"
:
return
hmac
.
New
(
sha1
.
New
,
key
),
sha1
.
Size
case
"SHA512"
:
return
hmac
.
New
(
sha512
.
New
,
key
),
sha512
.
Size
default
:
return
hmac
.
New
(
sha256
.
New
,
key
),
sha256
.
Size
}
return
peer
.
ID
(
hash
),
nil
}
// Generates a set of keys for each party by stretching the shared key.
// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey)
func
keyGenerator
(
cmp
int
,
cipherType
string
,
hashType
string
,
secret
[]
byte
)
([]
byte
,
[]
byte
,
[]
byte
,
[]
byte
,
[]
byte
,
[]
byte
)
{
var
cipherKeySize
int
switch
cipherType
{
case
"AES-128"
:
cipherKeySize
=
16
case
"AES-256"
:
cipherKeySize
=
32
}
ivSize
:=
16
hmacKeySize
:=
20
seed
:=
[]
byte
(
"key expansion"
)
func
secureInProxy
(
in
,
secureIn
chan
[]
byte
,
hashType
string
,
tIV
,
tCKey
,
tMKey
[]
byte
)
{
theirBlock
,
_
:=
aes
.
NewCipher
(
tCKey
)
theirCipher
:=
cipher
.
NewCTR
(
theirBlock
,
tIV
)
result
:=
make
([]
byte
,
2
*
(
ivSize
+
cipherKeySize
+
hmacKeySize
)
)
theirMac
,
macSize
:=
makeMac
(
hashType
,
tMKey
)
var
h
func
()
hash
.
Hash
for
{
data
,
ok
:=
<-
in
if
!
ok
{
return
}
switch
hashType
{
case
"SHA1"
:
h
=
sha1
.
New
case
"SHA256"
:
h
=
sha256
.
New
case
"SHA512"
:
h
=
sha512
.
New
}
if
len
(
data
)
<=
macSize
{
continue
}
m
:=
hmac
.
New
(
h
,
secret
)
m
.
Write
(
seed
)
m
ark
:=
len
(
data
)
-
macSize
buff
:=
make
([]
byte
,
mark
)
a
:=
m
.
Sum
(
nil
)
theirCipher
.
XORKeyStream
(
buff
,
data
[
0
:
mark
]
)
j
:=
0
for
j
<
len
(
result
)
{
m
.
Reset
()
m
.
Write
(
a
)
m
.
Write
(
seed
)
b
:=
m
.
Sum
(
nil
)
theirMac
.
Write
(
data
[
0
:
mark
])
expected
:=
theirMac
.
Sum
(
nil
)
theirMac
.
Reset
()
todo
:=
len
(
b
)
hmacOk
:=
hmac
.
Equal
(
data
[
mark
:
],
expected
)
if
j
+
todo
>
len
(
result
)
{
todo
=
len
(
result
)
-
j
if
hmacOk
{
secureIn
<-
buff
}
else
{
secureIn
<-
nil
}
}
}
copy
(
result
[
j
:
j
+
todo
],
b
)
func
secureOutProxy
(
out
,
secureOut
chan
[]
byte
,
hashType
string
,
mIV
,
mCKey
,
mMKey
[]
byte
)
{
myBlock
,
_
:=
aes
.
NewCipher
(
mCKey
)
myCipher
:=
cipher
.
NewCTR
(
myBlock
,
mIV
)
j
+=
todo
myMac
,
macSize
:=
makeMac
(
hashType
,
mMKey
)
m
.
Reset
()
m
.
Write
(
a
)
a
=
m
.
Sum
(
nil
)
}
for
{
data
,
ok
:=
<-
secureOut
if
!
ok
{
return
}
myResult
:=
make
([]
byte
,
ivSize
+
cipherKeySize
+
hmacKeySize
)
theirResult
:=
make
([]
byte
,
ivSize
+
cipherKeySize
+
hmacKeySize
)
if
len
(
data
)
==
0
{
continue
}
hal
f
:=
len
(
result
)
/
2
buf
f
:=
make
([]
byte
,
len
(
data
)
+
macSize
)
if
cmp
==
1
{
copy
(
myResult
,
result
[
:
half
])
copy
(
theirResult
,
result
[
half
:
])
}
else
if
cmp
==
-
1
{
copy
(
myResult
,
result
[
half
:
])
copy
(
theirResult
,
result
[
:
half
])
}
else
{
// Shouldn't happen, but oh well.
copy
(
myResult
,
result
[
half
:
])
copy
(
theirResult
,
result
[
half
:
])
}
myCipher
.
XORKeyStream
(
buff
,
data
)
myIV
:=
myResult
[
0
:
ivSize
]
myCKey
:=
myResult
[
ivSize
:
ivSize
+
cipherKeySize
]
myM
Key
:=
myResult
[
ivSize
+
cipherKeySize
:
]
myMac
.
Write
(
buff
[
0
:
len
(
data
)])
copy
(
buff
[
len
(
data
)
:
],
myMac
.
Sum
(
nil
))
myM
ac
.
Reset
()
theirIV
:=
theirResult
[
0
:
ivSize
]
theirCKey
:=
theirResult
[
ivSize
:
ivSize
+
cipherKeySize
]
theirMKey
:=
theirResult
[
ivSize
+
cipherKeySize
:
]
out
<-
buff
}
}
return
myIV
,
theirIV
,
myCKey
,
theirCKey
,
myMKey
,
theirMKey
func
IdFromPubKey
(
pk
ci
.
PubKey
)
(
peer
.
ID
,
error
)
{
b
,
err
:=
pk
.
Bytes
()
if
err
!=
nil
{
return
nil
,
err
}
hash
,
err
:=
u
.
Hash
(
b
)
if
err
!=
nil
{
return
nil
,
err
}
return
peer
.
ID
(
hash
),
nil
}
// Determines which algorithm to use. Note: f(a, b) = f(b, a)
...
...
@@ -372,96 +288,3 @@ func selectBest(myPrefs, theirPrefs string) (string, error) {
return
""
,
errors
.
New
(
"No algorithms in common!"
)
}
// Generates an ephemeral public key and returns a function that will compute
// the shared secret key.
//
// Focuses only on ECDH now, but can be made more general in the future.
func
generateEPubKey
(
exchange
string
)
([]
byte
,
func
([]
byte
)
([]
byte
,
error
),
error
)
{
genKeyPair
:=
func
(
curve
elliptic
.
Curve
)
([]
byte
,
[]
byte
,
error
)
{
priv
,
x
,
y
,
err
:=
elliptic
.
GenerateKey
(
curve
,
rand
.
Reader
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
var
pubKey
bytes
.
Buffer
pubKey
.
Write
(
x
.
Bytes
())
pubKey
.
Write
(
y
.
Bytes
())
return
pubKey
.
Bytes
(),
priv
,
nil
}
genSec
:=
func
(
curve
elliptic
.
Curve
,
theirPub
[]
byte
,
myPriv
[]
byte
)
([]
byte
,
error
)
{
// Verify and unpack node's public key.
curveSize
:=
curve
.
Params
()
.
BitSize
if
len
(
theirPub
)
!=
(
curveSize
/
4
)
{
return
nil
,
errors
.
New
(
"Malformed public key."
)
}
bound
:=
(
curveSize
/
8
)
x
:=
big
.
NewInt
(
0
)
y
:=
big
.
NewInt
(
0
)
x
.
SetBytes
(
theirPub
[
0
:
bound
])
y
.
SetBytes
(
theirPub
[
bound
:
bound
*
2
])
if
!
curve
.
IsOnCurve
(
x
,
y
)
{
return
nil
,
errors
.
New
(
"Invalid public key."
)
}
// Generate shared secret.
secret
,
_
:=
curve
.
ScalarMult
(
x
,
y
,
myPriv
)
return
secret
.
Bytes
(),
nil
}
switch
exchange
{
case
"P-224"
:
curve
:=
elliptic
.
P224
()
pub
,
priv
,
err
:=
genKeyPair
(
curve
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
done
:=
func
(
theirs
[]
byte
)
([]
byte
,
error
)
{
return
genSec
(
curve
,
theirs
,
priv
)
}
return
pub
,
done
,
nil
case
"P-256"
:
curve
:=
elliptic
.
P256
()
pub
,
priv
,
err
:=
genKeyPair
(
curve
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
done
:=
func
(
theirs
[]
byte
)
([]
byte
,
error
)
{
return
genSec
(
curve
,
theirs
,
priv
)
}
return
pub
,
done
,
nil
case
"P-384"
:
curve
:=
elliptic
.
P384
()
pub
,
priv
,
err
:=
genKeyPair
(
curve
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
done
:=
func
(
theirs
[]
byte
)
([]
byte
,
error
)
{
return
genSec
(
curve
,
theirs
,
priv
)
}
return
pub
,
done
,
nil
case
"P-521"
:
curve
:=
elliptic
.
P521
()
pub
,
priv
,
err
:=
genKeyPair
(
curve
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
done
:=
func
(
theirs
[]
byte
)
([]
byte
,
error
)
{
return
genSec
(
curve
,
theirs
,
priv
)
}
return
pub
,
done
,
nil
}
return
nil
,
nil
,
errors
.
New
(
"Something silly happened."
)
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment