Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IRMA
Github mirrors
irmago
Commits
1d75fcb4
Commit
1d75fcb4
authored
Oct 03, 2017
by
Sietse Ringers
Browse files
Fix code reuse in storage
parent
ea159ad6
Changes
3
Hide whitespace changes
Inline
Side-by-side
manager.go
View file @
1d75fcb4
...
...
@@ -3,7 +3,6 @@ package irmago
import
(
"crypto/rand"
"math/big"
"os"
"sort"
"time"
...
...
@@ -77,7 +76,7 @@ func NewCredentialManager(
}
// Ensure storage path exists, and populate it with necessary files
if
err
=
cm
.
storage
.
e
nsureStorageExists
();
err
!=
nil
{
if
err
=
cm
.
storage
.
E
nsureStorageExists
();
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -87,16 +86,16 @@ func NewCredentialManager(
}
// Load our stuff
if
cm
.
secretkey
,
err
=
cm
.
storage
.
l
oadSecretKey
();
err
!=
nil
{
if
cm
.
secretkey
,
err
=
cm
.
storage
.
L
oadSecretKey
();
err
!=
nil
{
return
nil
,
err
}
if
cm
.
attributes
,
err
=
cm
.
storage
.
l
oadAttributes
();
err
!=
nil
{
if
cm
.
attributes
,
err
=
cm
.
storage
.
L
oadAttributes
();
err
!=
nil
{
return
nil
,
err
}
if
cm
.
paillierKeyCache
,
err
=
cm
.
storage
.
l
oadPaillierKeys
();
err
!=
nil
{
if
cm
.
paillierKeyCache
,
err
=
cm
.
storage
.
L
oadPaillierKeys
();
err
!=
nil
{
return
nil
,
err
}
if
cm
.
keyshareServers
,
err
=
cm
.
storage
.
l
oadKeyshareServers
();
err
!=
nil
{
if
cm
.
keyshareServers
,
err
=
cm
.
storage
.
L
oadKeyshareServers
();
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -142,7 +141,7 @@ func (cm *CredentialManager) remove(id CredentialTypeIdentifier, index int, stor
attrs
:=
list
[
index
]
cm
.
attributes
[
id
]
=
append
(
list
[
:
index
],
list
[
index
+
1
:
]
...
)
if
storenow
{
cm
.
storage
.
s
toreAttributes
(
cm
.
attributes
)
cm
.
storage
.
S
toreAttributes
(
cm
.
attributes
)
}
// Remove credential
...
...
@@ -154,7 +153,7 @@ func (cm *CredentialManager) remove(id CredentialTypeIdentifier, index int, stor
}
// Remove signature from storage
if
err
:=
os
.
Remove
(
cm
.
storage
.
s
ignature
Filename
(
attrs
)
)
;
err
!=
nil
{
if
err
:=
cm
.
storage
.
DeleteS
ignature
(
attrs
);
err
!=
nil
{
return
err
}
...
...
@@ -184,10 +183,10 @@ func (cm *CredentialManager) RemoveAllCredentials() error {
return
err
}
}
if
err
:=
cm
.
storage
.
s
toreAttributes
(
cm
.
attributes
);
err
!=
nil
{
if
err
:=
cm
.
storage
.
S
toreAttributes
(
cm
.
attributes
);
err
!=
nil
{
return
err
}
return
cm
.
storage
.
s
toreLogs
(
cm
.
logs
)
return
cm
.
storage
.
S
toreLogs
(
cm
.
logs
)
}
// attrs returns cm.attributes[id], initializing it to an empty slice if neccesary
...
...
@@ -245,7 +244,7 @@ func (cm *CredentialManager) credential(id CredentialTypeIdentifier, counter int
if
attrs
==
nil
{
// We do not have the requested cred
return
}
sig
,
err
:=
cm
.
storage
.
l
oadSignature
(
attrs
)
sig
,
err
:=
cm
.
storage
.
L
oadSignature
(
attrs
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -286,11 +285,11 @@ func (cm *CredentialManager) addCredential(cred *credential, storeAttributes boo
counter
:=
len
(
cm
.
attributes
[
id
])
-
1
cm
.
credentials
[
id
][
counter
]
=
cred
if
err
=
cm
.
storage
.
s
toreSignature
(
cred
);
err
!=
nil
{
if
err
=
cm
.
storage
.
S
toreSignature
(
cred
);
err
!=
nil
{
return
}
if
storeAttributes
{
err
=
cm
.
storage
.
s
toreAttributes
(
cm
.
attributes
)
err
=
cm
.
storage
.
S
toreAttributes
(
cm
.
attributes
)
}
return
}
...
...
@@ -550,7 +549,7 @@ func (cm *CredentialManager) KeyshareEnroll(managerID SchemeManagerIdentifier, e
}
cm
.
keyshareServers
[
managerID
]
=
kss
return
cm
.
storage
.
s
toreKeyshareServers
(
cm
.
keyshareServers
)
return
cm
.
storage
.
S
toreKeyshareServers
(
cm
.
keyshareServers
)
}
// KeyshareRemove unregisters the keyshare server of the specified scheme manager.
...
...
@@ -559,13 +558,13 @@ func (cm *CredentialManager) KeyshareRemove(manager SchemeManagerIdentifier) err
return
errors
.
New
(
"Can't uninstall unknown keyshare server"
)
}
delete
(
cm
.
keyshareServers
,
manager
)
return
cm
.
storage
.
s
toreKeyshareServers
(
cm
.
keyshareServers
)
return
cm
.
storage
.
S
toreKeyshareServers
(
cm
.
keyshareServers
)
}
func
(
cm
*
CredentialManager
)
addLogEntry
(
entry
*
LogEntry
,
storenow
bool
)
error
{
cm
.
logs
=
append
(
cm
.
logs
,
entry
)
if
storenow
{
return
cm
.
storage
.
s
toreLogs
(
cm
.
logs
)
return
cm
.
storage
.
S
toreLogs
(
cm
.
logs
)
}
return
nil
}
...
...
@@ -573,10 +572,18 @@ func (cm *CredentialManager) addLogEntry(entry *LogEntry, storenow bool) error {
func
(
cm
*
CredentialManager
)
Logs
()
([]
*
LogEntry
,
error
)
{
if
cm
.
logs
==
nil
||
len
(
cm
.
logs
)
==
0
{
var
err
error
cm
.
logs
,
err
=
cm
.
storage
.
l
oadLogs
()
cm
.
logs
,
err
=
cm
.
storage
.
L
oadLogs
()
if
err
!=
nil
{
return
nil
,
err
}
}
return
cm
.
logs
,
nil
}
func
generateSecretKey
()
(
*
secretKey
,
error
)
{
key
,
err
:=
gabi
.
RandomBigInt
(
gabi
.
DefaultSystemParameters
[
1024
]
.
Lm
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
secretKey
{
Key
:
key
},
nil
}
storage.go
View file @
1d75fcb4
...
...
@@ -12,6 +12,9 @@ import (
"github.com/mhe/gabi"
)
// This file contains the storage struct and its methods,
// and some general filesystem functions.
// Storage provider for a CredentialManager
type
storage
struct
{
storagePath
string
...
...
@@ -89,63 +92,64 @@ func saveFile(filepath string, content []byte) (err error) {
return
os
.
Rename
(
dir
+
"/"
+
tempfilename
,
filepath
)
}
func
generateSecretKey
()
(
*
secretKey
,
error
)
{
key
,
err
:=
gabi
.
RandomBigInt
(
gabi
.
DefaultSystemParameters
[
1024
]
.
Lm
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
secretKey
{
Key
:
key
},
nil
}
func
(
s
*
storage
)
path
(
p
string
)
string
{
return
s
.
storagePath
+
"/"
+
p
}
func
(
s
*
storage
)
signatureFilename
(
attrs
*
AttributeList
)
string
{
// We take the SHA256 hash over all attributes as the filename for the signature.
// This means that the signatures of two credentials that have identical attributes
// will be written to the same file, one overwriting the other - but that doesn't
// matter, because either one of the signatures is valid over both attribute lists,
// so keeping one of them suffices.
return
s
.
path
(
signaturesDir
)
+
"/"
+
attrs
.
hash
()
}
// ensureStorageExists initializes the credential storage folder,
// EnsureStorageExists initializes the credential storage folder,
// ensuring that it is in a usable state.
// NOTE: we do not create the folder if it does not exist!
// Setting it up in a properly protected location (e.g., with automatic
// backups to iCloud/Google disabled) is the responsibility of the user.
func
(
s
*
storage
)
e
nsureStorageExists
()
error
{
func
(
s
*
storage
)
E
nsureStorageExists
()
error
{
if
err
:=
AssertPathExists
(
s
.
storagePath
);
err
!=
nil
{
return
err
}
return
ensureDirectoryExists
(
s
.
path
(
signaturesDir
))
}
func
(
s
*
storage
)
storeSecretKey
(
sk
*
secretKey
)
error
{
bytes
,
err
:=
json
.
Marshal
(
sk
)
func
(
s
*
storage
)
load
(
dest
interface
{},
path
string
)
(
err
error
)
{
exists
,
err
:=
PathExists
(
s
.
path
(
path
))
if
err
!=
nil
||
!
exists
{
return
}
bytes
,
err
:=
ioutil
.
ReadFile
(
s
.
path
(
path
))
if
err
!=
nil
{
return
err
return
}
return
saveFile
(
s
.
path
(
skFile
),
bytes
)
return
json
.
Unmarshal
(
bytes
,
dest
)
}
func
(
s
*
storage
)
storeSignature
(
cred
*
credential
)
(
err
error
)
{
if
cred
.
CredentialType
()
==
nil
{
return
errors
.
New
(
"cannot add unknown credential type"
)
}
credbytes
,
err
:=
json
.
Marshal
(
cred
.
Signature
)
func
(
s
*
storage
)
store
(
contents
interface
{},
file
string
)
error
{
bts
,
err
:=
json
.
Marshal
(
contents
)
if
err
!=
nil
{
return
err
}
return
saveFile
(
s
.
path
(
file
),
bts
)
}
func
(
s
*
storage
)
signatureFilename
(
attrs
*
AttributeList
)
string
{
// We take the SHA256 hash over all attributes as the filename for the signature.
// This means that the signatures of two credentials that have identical attributes
// will be written to the same file, one overwriting the other - but that doesn't
// matter, because either one of the signatures is valid over both attribute lists,
// so keeping one of them suffices.
return
signaturesDir
+
"/"
+
attrs
.
hash
()
}
func
(
s
*
storage
)
DeleteSignature
(
attrs
*
AttributeList
)
error
{
return
os
.
Remove
(
s
.
path
(
s
.
signatureFilename
(
attrs
)))
}
filename
:=
s
.
signatureFilename
(
cred
.
AttributeList
())
err
=
saveFile
(
filename
,
credbytes
)
return
func
(
s
*
storage
)
StoreSignature
(
cred
*
credential
)
error
{
return
s
.
store
(
cred
.
Signature
,
s
.
signatureFilename
(
cred
.
AttributeList
()))
}
func
(
s
*
storage
)
storeAttributes
(
attributes
map
[
CredentialTypeIdentifier
][]
*
AttributeList
)
error
{
func
(
s
*
storage
)
StoreSecretKey
(
sk
*
secretKey
)
error
{
return
s
.
store
(
sk
,
skFile
)
}
func
(
s
*
storage
)
StoreAttributes
(
attributes
map
[
CredentialTypeIdentifier
][]
*
AttributeList
)
error
{
temp
:=
[]
*
AttributeList
{}
for
_
,
attrlistlist
:=
range
attributes
{
for
_
,
attrlist
:=
range
attrlistlist
{
...
...
@@ -153,110 +157,66 @@ func (s *storage) storeAttributes(attributes map[CredentialTypeIdentifier][]*Att
}
}
if
attrbytes
,
err
:=
json
.
Marshal
(
temp
);
err
==
nil
{
return
saveFile
(
s
.
path
(
attributesFile
),
attrbytes
)
}
else
{
return
err
}
return
s
.
store
(
temp
,
attributesFile
)
}
func
(
s
*
storage
)
storeKeyshareServers
(
keyshareServers
map
[
SchemeManagerIdentifier
]
*
keyshareServer
)
(
err
error
)
{
bts
,
err
:=
json
.
Marshal
(
keyshareServers
)
if
err
!=
nil
{
return
}
err
=
saveFile
(
s
.
path
(
kssFile
),
bts
)
return
func
(
s
*
storage
)
StoreKeyshareServers
(
keyshareServers
map
[
SchemeManagerIdentifier
]
*
keyshareServer
)
(
err
error
)
{
return
s
.
store
(
keyshareServers
,
kssFile
)
}
func
(
s
*
storage
)
storePaillierKeys
(
key
*
paillierPrivateKey
)
(
err
error
)
{
bts
,
err
:=
json
.
Marshal
(
key
)
if
err
!=
nil
{
return
}
err
=
saveFile
(
s
.
path
(
paillierFile
),
bts
)
return
func
(
s
*
storage
)
StorePaillierKeys
(
key
*
paillierPrivateKey
)
(
err
error
)
{
return
s
.
store
(
key
,
paillierFile
)
}
func
(
s
*
storage
)
storeLogs
(
logs
[]
*
LogEntry
)
(
err
error
)
{
bts
,
err
:=
json
.
Marshal
(
logs
)
if
err
!=
nil
{
return
}
err
=
saveFile
(
s
.
path
(
logsFile
),
bts
)
return
func
(
s
*
storage
)
StoreLogs
(
logs
[]
*
LogEntry
)
(
err
error
)
{
return
s
.
store
(
logs
,
logsFile
)
}
func
(
s
*
storage
)
storeUpdates
(
updates
[]
update
)
(
err
error
)
{
bts
,
err
:=
json
.
Marshal
(
updates
)
if
err
!=
nil
{
return
}
err
=
saveFile
(
s
.
path
(
updatesFile
),
bts
)
return
func
(
s
*
storage
)
StoreUpdates
(
updates
[]
update
)
(
err
error
)
{
return
s
.
store
(
updates
,
updatesFile
)
}
func
(
s
*
storage
)
l
oadSignature
(
attrs
*
AttributeList
)
(
signature
*
gabi
.
CLSignature
,
err
error
)
{
func
(
s
*
storage
)
L
oadSignature
(
attrs
*
AttributeList
)
(
signature
*
gabi
.
CLSignature
,
err
error
)
{
sigpath
:=
s
.
signatureFilename
(
attrs
)
if
err
:=
AssertPathExists
(
sigpath
);
err
!=
nil
{
if
err
:=
AssertPathExists
(
s
.
path
(
sigpath
)
)
;
err
!=
nil
{
return
nil
,
err
}
bytes
,
err
:=
ioutil
.
ReadFile
(
sigpath
)
if
err
!=
nil
{
return
}
signature
=
new
(
gabi
.
CLSignature
)
err
=
json
.
Unmarshal
(
bytes
,
signature
)
return
if
err
:=
s
.
load
(
signature
,
sigpath
);
err
!=
nil
{
return
nil
,
err
}
return
signature
,
nil
}
//
l
oadSecretKey retrieves and returns the secret key from storage, or if no secret key
//
L
oadSecretKey retrieves and returns the secret key from storage, or if no secret key
// was found in storage, it generates, saves, and returns a new secret key.
func
(
s
*
storage
)
loadSecretKey
()
(
*
secretKey
,
error
)
{
sk
:=
&
secretKey
{}
func
(
s
*
storage
)
LoadSecretKey
()
(
*
secretKey
,
error
)
{
var
err
error
exists
,
err
:=
PathExists
(
s
.
path
(
skFile
))
if
err
!=
nil
{
sk
:=
&
secretKey
{}
if
err
=
s
.
load
(
sk
,
skFile
);
err
!=
nil
{
return
nil
,
err
}
if
exists
{
var
bytes
[]
byte
if
bytes
,
err
=
ioutil
.
ReadFile
(
s
.
path
(
skFile
));
err
!=
nil
{
return
nil
,
err
}
if
err
=
json
.
Unmarshal
(
bytes
,
sk
);
err
!=
nil
{
return
nil
,
err
}
return
sk
,
err
if
sk
.
Key
!=
nil
{
return
sk
,
nil
}
sk
,
err
=
generateSecretKey
()
if
err
!=
nil
{
if
sk
,
err
=
generateSecretKey
();
err
!=
nil
{
return
nil
,
err
}
err
=
s
.
storeSecretKey
(
sk
)
if
err
!=
nil
{
if
err
=
s
.
StoreSecretKey
(
sk
);
err
!=
nil
{
return
nil
,
err
}
return
sk
,
nil
}
func
(
s
*
storage
)
loadAttributes
()
(
list
map
[
CredentialTypeIdentifier
][]
*
AttributeList
,
err
error
)
{
exists
,
err
:=
PathExists
(
s
.
path
(
attributesFile
))
if
err
!=
nil
||
!
exists
{
func
(
s
*
storage
)
LoadAttributes
()
(
list
map
[
CredentialTypeIdentifier
][]
*
AttributeList
,
err
error
)
{
// The attributes are stored as a list of instances of AttributeList
temp
:=
[]
*
AttributeList
{}
if
err
=
s
.
load
(
&
temp
,
attributesFile
);
err
!=
nil
{
return
}
bytes
,
err
:=
ioutil
.
ReadFile
(
s
.
path
(
attributesFile
))
if
err
!=
nil
{
return
nil
,
err
}
// The attributes are stored as a list of instances of AttributeList
temp
:=
[]
*
AttributeList
{}
list
=
make
(
map
[
CredentialTypeIdentifier
][]
*
AttributeList
)
if
err
=
json
.
Unmarshal
(
bytes
,
&
temp
);
err
!=
nil
{
return
nil
,
err
}
for
_
,
attrlist
:=
range
temp
{
attrlist
.
MetadataAttribute
=
MetadataFromInt
(
attrlist
.
Ints
[
0
],
s
.
ConfigurationStore
)
id
:=
attrlist
.
CredentialType
()
...
...
@@ -273,70 +233,34 @@ func (s *storage) loadAttributes() (list map[CredentialTypeIdentifier][]*Attribu
return
list
,
nil
}
func
(
s
*
storage
)
l
oadKeyshareServers
()
(
ksses
map
[
SchemeManagerIdentifier
]
*
keyshareServer
,
err
error
)
{
func
(
s
*
storage
)
L
oadKeyshareServers
()
(
ksses
map
[
SchemeManagerIdentifier
]
*
keyshareServer
,
err
error
)
{
ksses
=
make
(
map
[
SchemeManagerIdentifier
]
*
keyshareServer
)
exists
,
err
:=
PathExists
(
s
.
path
(
kssFile
))
if
err
!=
nil
||
!
exists
{
return
}
bytes
,
err
:=
ioutil
.
ReadFile
(
s
.
path
(
kssFile
))
if
err
!=
nil
{
if
err
:=
s
.
load
(
&
ksses
,
kssFile
);
err
!=
nil
{
return
nil
,
err
}
err
=
json
.
Unmarshal
(
bytes
,
&
ksses
)
if
err
!=
nil
{
return
nil
,
err
}
return
return
ksses
,
nil
}
func
(
s
*
storage
)
loadPaillierKeys
()
(
key
*
paillierPrivateKey
,
err
error
)
{
exists
,
err
:=
PathExists
(
s
.
path
(
paillierFile
))
if
err
!=
nil
||
!
exists
{
return
}
bytes
,
err
:=
ioutil
.
ReadFile
(
s
.
path
(
paillierFile
))
if
err
!=
nil
{
return
nil
,
err
}
func
(
s
*
storage
)
LoadPaillierKeys
()
(
key
*
paillierPrivateKey
,
err
error
)
{
key
=
new
(
paillierPrivateKey
)
err
=
json
.
Unmarshal
(
bytes
,
key
)
if
err
!=
nil
{
if
err
:=
s
.
load
(
key
,
paillierFile
);
err
!=
nil
{
return
nil
,
err
}
return
return
key
,
nil
}
func
(
s
*
storage
)
l
oadLogs
()
(
logs
[]
*
LogEntry
,
err
error
)
{
func
(
s
*
storage
)
L
oadLogs
()
(
logs
[]
*
LogEntry
,
err
error
)
{
logs
=
[]
*
LogEntry
{}
exists
,
err
:=
PathExists
(
s
.
path
(
logsFile
))
if
err
!=
nil
||
!
exists
{
return
}
bytes
,
err
:=
ioutil
.
ReadFile
(
s
.
path
(
logsFile
))
if
err
!=
nil
{
return
nil
,
err
}
err
=
json
.
Unmarshal
(
bytes
,
&
logs
)
if
err
!=
nil
{
if
err
:=
s
.
load
(
&
logs
,
logsFile
);
err
!=
nil
{
return
nil
,
err
}
return
return
logs
,
nil
}
func
(
s
*
storage
)
l
oadUpdates
()
(
updates
[]
update
,
err
error
)
{
func
(
s
*
storage
)
L
oadUpdates
()
(
updates
[]
update
,
err
error
)
{
updates
=
[]
update
{}
exists
,
err
:=
PathExists
(
s
.
path
(
updatesFile
))
if
err
!=
nil
||
!
exists
{
return
}
bytes
,
err
:=
ioutil
.
ReadFile
(
s
.
path
(
updatesFile
))
if
err
!=
nil
{
return
nil
,
err
}
err
=
json
.
Unmarshal
(
bytes
,
&
updates
)
if
err
!=
nil
{
if
err
:=
s
.
load
(
&
updates
,
updatesFile
);
err
!=
nil
{
return
nil
,
err
}
return
return
updates
,
nil
}
updates.go
View file @
1d75fcb4
...
...
@@ -12,6 +12,9 @@ import (
"github.com/mhe/gabi"
)
// This file contains the update mechanism for CredentialManager
// as well as updates themselves.
type
update
struct
{
When
Timestamp
Number
int
...
...
@@ -32,7 +35,7 @@ var credentialManagerUpdates = []func(manager *CredentialManager) error{
func
(
cm
*
CredentialManager
)
update
()
error
{
// Load and parse file containing info about already performed updates
var
err
error
if
cm
.
updates
,
err
=
cm
.
storage
.
l
oadUpdates
();
err
!=
nil
{
if
cm
.
updates
,
err
=
cm
.
storage
.
L
oadUpdates
();
err
!=
nil
{
return
err
}
...
...
@@ -51,7 +54,7 @@ func (cm *CredentialManager) update() error {
cm
.
updates
=
append
(
cm
.
updates
,
update
)
}
cm
.
storage
.
s
toreUpdates
(
cm
.
updates
)
cm
.
storage
.
S
toreUpdates
(
cm
.
updates
)
return
nil
}
...
...
@@ -140,21 +143,21 @@ func (cm *CredentialManager) ParseAndroidStorage() (present bool, err error) {
}
if
len
(
cm
.
credentials
)
>
0
{
if
err
=
cm
.
storage
.
s
toreAttributes
(
cm
.
attributes
);
err
!=
nil
{
if
err
=
cm
.
storage
.
S
toreAttributes
(
cm
.
attributes
);
err
!=
nil
{
return
}
if
err
=
cm
.
storage
.
s
toreSecretKey
(
cm
.
secretkey
);
err
!=
nil
{
if
err
=
cm
.
storage
.
S
toreSecretKey
(
cm
.
secretkey
);
err
!=
nil
{
return
}
}
if
len
(
cm
.
keyshareServers
)
>
0
{
if
err
=
cm
.
storage
.
s
toreKeyshareServers
(
cm
.
keyshareServers
);
err
!=
nil
{
if
err
=
cm
.
storage
.
S
toreKeyshareServers
(
cm
.
keyshareServers
);
err
!=
nil
{
return
}
}
if
err
=
cm
.
storage
.
s
torePaillierKeys
(
cm
.
paillierKeyCache
);
err
!=
nil
{
if
err
=
cm
.
storage
.
S
torePaillierKeys
(
cm
.
paillierKeyCache
);
err
!=
nil
{
return
}
if
cm
.
paillierKeyCache
==
nil
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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