Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
bee7119e
Commit
bee7119e
authored
Oct 28, 2015
by
Matt Perry
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add some unit tests for flx signing code.
parent
02a1ebab
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
132 additions
and
26 deletions
+132
-26
signing.dart
packages/flx/lib/signing.dart
+28
-25
pubspec.yaml
packages/flx/pubspec.yaml
+1
-1
pubspec.yaml
packages/unit/pubspec.yaml
+3
-0
signing_test.dart
packages/unit/test/flx/signing_test.dart
+100
-0
No files found.
packages/flx/lib/signing.dart
View file @
bee7119e
...
...
@@ -4,7 +4,6 @@
import
'dart:async'
;
import
'dart:convert'
;
import
'dart:math'
;
import
'dart:io'
;
import
'dart:typed_data'
;
...
...
@@ -44,7 +43,7 @@ final CipherParameters _params = _initParams();
Uint8List
serializeManifest
(
Map
manifestDescriptor
,
ECPublicKey
publicKey
,
Uint8List
zipBytes
)
{
if
(
manifestDescriptor
==
null
)
return
null
;
final
List
<
String
>
kSavedKeys
=
[
final
List
<
String
>
kSavedKeys
=
<
String
>
[
'name'
,
'version'
,
'update-url'
...
...
@@ -66,9 +65,9 @@ Uint8List serializeManifest(Map manifestDescriptor, ECPublicKey publicKey, Uint8
}
// Returns the ASN.1 encoded signature of the input manifestBytes.
List
<
int
>
signManifest
(
Uint8List
manifestBytes
,
ECPrivateKey
privateKey
)
{
Uint8List
signManifest
(
Uint8List
manifestBytes
,
ECPrivateKey
privateKey
)
{
if
(
manifestBytes
==
null
||
privateKey
==
null
)
return
[]
;
return
new
Uint8List
(
0
)
;
Signer
signer
=
new
Signer
(
_params
.
signerAlgorithm
);
PrivateKeyParameter
params
=
new
PrivateKeyParameter
(
privateKey
);
signer
.
init
(
true
,
new
ParametersWithRandom
(
params
,
_params
.
random
));
...
...
@@ -121,26 +120,22 @@ ECPrivateKey _asn1ParsePrivateKey(ECDomainParameters ecDomain, Uint8List private
// Parses a DER-encoded ASN.1 ECDSA signature block.
ECSignature
_asn1ParseSignature
(
Uint8List
signature
)
{
ASN1Parser
parser
=
new
ASN1Parser
(
signature
);
ASN1Object
object
=
parser
.
nextObject
();
if
(
object
is
!
ASN1Sequence
)
return
null
;
ASN1Sequence
sequence
=
object
;
if
(!(
sequence
.
elements
.
length
==
2
&&
sequence
.
elements
[
0
]
is
ASN1Integer
&&
sequence
.
elements
[
1
]
is
ASN1Integer
))
return
null
;
ASN1Integer
r
=
sequence
.
elements
[
0
];
ASN1Integer
s
=
sequence
.
elements
[
1
];
return
new
ECSignature
(
r
.
valueAsPositiveBigInteger
,
s
.
valueAsPositiveBigInteger
);
}
ECPrivateKey
_readPrivateKeySync
(
String
privateKeyPath
)
{
File
file
=
new
File
(
privateKeyPath
);
if
(!
file
.
existsSync
())
try
{
ASN1Parser
parser
=
new
ASN1Parser
(
signature
);
ASN1Object
object
=
parser
.
nextObject
();
if
(
object
is
!
ASN1Sequence
)
return
null
;
ASN1Sequence
sequence
=
object
;
if
(!(
sequence
.
elements
.
length
==
2
&&
sequence
.
elements
[
0
]
is
ASN1Integer
&&
sequence
.
elements
[
1
]
is
ASN1Integer
))
return
null
;
ASN1Integer
r
=
sequence
.
elements
[
0
];
ASN1Integer
s
=
sequence
.
elements
[
1
];
return
new
ECSignature
(
r
.
valueAsPositiveBigInteger
,
s
.
valueAsPositiveBigInteger
);
}
on
ASN1Exception
{
return
null
;
List
<
int
>
bytes
=
file
.
readAsBytesSync
();
return
_asn1ParsePrivateKey
(
_params
.
domain
,
new
Uint8List
.
fromList
(
bytes
));
}
}
ECPublicKey
_publicKeyFromPrivateKey
(
ECPrivateKey
privateKey
)
{
...
...
@@ -154,8 +149,16 @@ class KeyPair {
ECPublicKey
publicKey
;
ECPrivateKey
privateKey
;
static
KeyPair
readFromPrivateKeySync
(
String
path
)
{
ECPrivateKey
privateKey
=
_readPrivateKeySync
(
path
);
static
KeyPair
readFromPrivateKeySync
(
String
privateKeyPath
)
{
File
file
=
new
File
(
privateKeyPath
);
if
(!
file
.
existsSync
())
return
null
;
return
fromPrivateKeyBytes
(
file
.
readAsBytesSync
());
}
static
KeyPair
fromPrivateKeyBytes
(
List
<
int
>
privateKeyBytes
)
{
ECPrivateKey
privateKey
=
_asn1ParsePrivateKey
(
_params
.
domain
,
new
Uint8List
.
fromList
(
privateKeyBytes
));
if
(
privateKey
==
null
)
return
null
;
...
...
packages/flx/pubspec.yaml
View file @
bee7119e
name
:
flx
version
:
0.0.
1
version
:
0.0.
2
author
:
Flutter Authors <flutter-dev@googlegroups.com>
description
:
Library for dealing with Flutter bundle (.flx) files
homepage
:
http://flutter.io
...
...
packages/unit/pubspec.yaml
View file @
bee7119e
...
...
@@ -4,8 +4,11 @@ dependencies:
sky_tools
:
any
test
:
any
quiver
:
any
flx
:
^0.0.2
dependency_overrides
:
material_design_icons
:
path
:
../packages/material_design_icons
flutter
:
path
:
../packages/sky
flx
:
path
:
../packages/flx
packages/unit/test/flx/signing_test.dart
0 → 100644
View file @
bee7119e
import
'dart:async'
;
import
'dart:convert'
;
import
'dart:typed_data'
;
import
'package:bignum/bignum.dart'
;
import
'package:flx/signing.dart'
;
import
'package:quiver/testing/async.dart'
;
import
'package:test/test.dart'
;
void
main
(
)
{
// The following constant was generated via the openssl shell commands:
// openssl ecparam -genkey -name prime256v1 -out privatekey.pem
// openssl ec -in privatekey.pem -outform DER | base64
const
String
kPrivateKeyBase64
=
'MHcCAQEEIG4Xt+MgsdP/o89kAHz7EVVLKkN+DUfpaBtZfMyFGbUgoAoGCCqGSM49AwEHoUQDQgAElPtbBVPPqKHYXYAgHaxB2hL6sXeFc99YLijTAuAPe2Nbhywan+v4k+nFm0TJJW/mkV+nH+fyBZ98t4UcFCqkOg=='
;
final
List
<
int
>
kPrivateKeyDER
=
BASE64
.
decode
(
kPrivateKeyBase64
);
// Unpacked values of the above private key.
const
int
kPrivateKeyD
=
0x6e17b7e320b1d3ffa3cf64007cfb11554b2a437e0d47e9681b597ccc8519b520
;
const
int
kPublicKeyQx
=
0x94fb5b0553cfa8a1d85d80201dac41da12fab1778573df582e28d302e00f7b63
;
const
int
kPublicKeyQy
=
0x5b872c1a9febf893e9c59b44c9256fe6915fa71fe7f2059f7cb7851c142aa43a
;
// Test manifest.
final
Map
<
String
,
dynamic
>
kManifest
=
<
String
,
dynamic
>{
'name'
:
'test app'
,
'version'
:
'1.0.0'
};
// Simple test byte pattern (flat and in chunked form) and its SHA-256 hash.
final
Uint8List
kTestBytes
=
new
Uint8List
.
fromList
(<
int
>[
1
,
2
,
3
]);
final
List
<
Uint8List
>
kTestBytesList
=
<
Uint8List
>[
new
Uint8List
.
fromList
(<
int
>[
1
,
2
]),
new
Uint8List
.
fromList
(<
int
>[
3
])];
final
int
kTestHash
=
0x039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81
;
test
(
'can read openssl key pair'
,
()
{
KeyPair
keyPair
=
KeyPair
.
fromPrivateKeyBytes
(
kPrivateKeyDER
);
expect
(
keyPair
!=
null
,
equals
(
true
));
expect
(
keyPair
.
privateKey
.
d
.
intValue
(),
equals
(
kPrivateKeyD
));
expect
(
keyPair
.
publicKey
.
Q
.
x
.
toBigInteger
().
intValue
(),
equals
(
kPublicKeyQx
));
expect
(
keyPair
.
publicKey
.
Q
.
y
.
toBigInteger
().
intValue
(),
equals
(
kPublicKeyQy
));
});
test
(
'serializeManifest adds key and content-hash'
,
()
{
KeyPair
keyPair
=
KeyPair
.
fromPrivateKeyBytes
(
kPrivateKeyDER
);
Uint8List
manifestBytes
=
serializeManifest
(
kManifest
,
keyPair
.
publicKey
,
kTestBytes
);
Map
<
String
,
dynamic
>
decodedManifest
=
JSON
.
decode
(
UTF8
.
decode
(
manifestBytes
));
String
expectedKey
=
BASE64
.
encode
(
keyPair
.
publicKey
.
Q
.
getEncoded
());
expect
(
decodedManifest
!=
null
,
equals
(
true
));
expect
(
decodedManifest
[
'name'
],
equals
(
kManifest
[
'name'
]));
expect
(
decodedManifest
[
'version'
],
equals
(
kManifest
[
'version'
]));
expect
(
decodedManifest
[
'key'
],
equals
(
expectedKey
));
expect
(
decodedManifest
[
'content-hash'
],
equals
(
kTestHash
));
});
test
(
'signManifest and verifyManifestSignature work'
,
()
{
KeyPair
keyPair
=
KeyPair
.
fromPrivateKeyBytes
(
kPrivateKeyDER
);
Map
<
String
,
dynamic
>
manifest
=
JSON
.
decode
(
UTF8
.
decode
(
serializeManifest
(
kManifest
,
keyPair
.
publicKey
,
kTestBytes
)));
Uint8List
signatureBytes
=
signManifest
(
kTestBytes
,
keyPair
.
privateKey
);
bool
verifies
=
verifyManifestSignature
(
manifest
,
kTestBytes
,
signatureBytes
);
expect
(
verifies
,
equals
(
true
));
// Ensure it fails with invalid signature or content.
Uint8List
badBytes
=
new
Uint8List
.
fromList
(<
int
>[
42
]);
verifies
=
verifyManifestSignature
(
manifest
,
kTestBytes
,
badBytes
);
expect
(
verifies
,
equals
(
false
));
verifies
=
verifyManifestSignature
(
manifest
,
badBytes
,
signatureBytes
);
expect
(
verifies
,
equals
(
false
));
});
test
(
'verifyContentHash works'
,
()
{
new
FakeAsync
().
run
((
FakeAsync
async
)
{
bool
verifies
;
Stream
contentStream
=
new
Stream
.
fromIterable
(
kTestBytesList
);
verifyContentHash
(
new
BigInteger
(
kTestHash
),
contentStream
).
then
((
bool
rv
)
{
verifies
=
rv
;
});
async
.
elapse
(
Duration
.
ZERO
);
expect
(
verifies
,
equals
(
true
));
// Ensure it fails with invalid hash or content.
verifies
=
null
;
contentStream
=
new
Stream
.
fromIterable
(
kTestBytesList
);
verifyContentHash
(
new
BigInteger
(
0xdeadbeef
),
contentStream
).
then
((
bool
rv
)
{
verifies
=
rv
;
});
async
.
elapse
(
Duration
.
ZERO
);
expect
(
verifies
,
equals
(
false
));
verifies
=
null
;
Stream
badContentStream
=
new
Stream
.
fromIterable
([
new
Uint8List
.
fromList
(<
int
>[
42
])]);
verifyContentHash
(
new
BigInteger
(
kTestHash
),
badContentStream
).
then
((
bool
rv
)
{
verifies
=
rv
;
});
async
.
elapse
(
Duration
.
ZERO
);
expect
(
verifies
,
equals
(
false
));
});
});
}
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