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
8d0c0554
Commit
8d0c0554
authored
Aug 08, 2019
by
Sietse Ringers
Browse files
feat: add revocation server endpoints to servercore
parent
33c3b9b6
Changes
3
Hide whitespace changes
Inline
Side-by-side
internal/servercore/api.go
View file @
8d0c0554
...
...
@@ -10,6 +10,7 @@ import (
"net/http"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
...
...
@@ -17,6 +18,7 @@ import (
"github.com/jasonlvhit/gocron"
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/gabi/big"
"github.com/privacybydesign/gabi/revocation"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/fs"
"github.com/privacybydesign/irmago/server"
...
...
@@ -168,6 +170,7 @@ func (s *Server) verifyPrivateKeys(configuration *server.Configuration) error {
if
err
=
db
.
LoadCurrent
();
err
!=
nil
{
return
server
.
LogError
(
err
)
}
s
.
conf
.
RevocableCredentials
[
credid
]
=
struct
{}{}
}
}
}
...
...
@@ -293,13 +296,21 @@ func (s *Server) CancelSession(token string) error {
return
nil
}
func
ParsePath
(
path
string
)
(
string
,
string
,
error
)
{
pattern
:=
regexp
.
MustCompile
(
"session/(
\\
w+)/?(|commitments|proofs|status|statusevents)$"
)
matches
:=
pattern
.
FindStringSubmatch
(
path
)
if
len
(
matches
)
!
=
3
{
return
""
,
""
,
server
.
LogWarning
(
errors
.
Errorf
(
"Invalid URL: %s"
,
path
))
func
ParsePath
(
path
string
)
(
token
,
noun
string
,
arg
[]
string
,
err
error
)
{
client
:=
regexp
.
MustCompile
(
"session/(
\\
w+)/?(|commitments|proofs|status|statusevents)$"
)
matches
:=
client
.
FindStringSubmatch
(
path
)
if
len
(
matches
)
=
=
3
{
return
matches
[
1
],
matches
[
2
],
nil
,
nil
}
return
matches
[
1
],
matches
[
2
],
nil
rev
:=
regexp
.
MustCompile
(
"-/revocation/(records)/?(.*)$"
)
matches
=
rev
.
FindStringSubmatch
(
path
)
if
len
(
matches
)
==
3
{
args
:=
strings
.
Split
(
matches
[
2
],
"/"
)
return
""
,
matches
[
1
],
args
,
nil
}
return
""
,
""
,
nil
,
server
.
LogWarning
(
errors
.
Errorf
(
"Invalid URL: %s"
,
path
))
}
func
(
s
*
Server
)
SubscribeServerSentEvents
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
token
string
,
requestor
bool
)
error
{
...
...
@@ -375,12 +386,22 @@ func (s *Server) handleProtocolMessage(
}
}
token
,
noun
,
err
:=
ParsePath
(
path
)
token
,
noun
,
args
,
err
:=
ParsePath
(
path
)
if
err
!=
nil
{
status
,
output
=
server
.
JsonResponse
(
nil
,
server
.
RemoteError
(
server
.
ErrorUnsupported
,
""
))
return
}
if
token
!=
""
{
status
,
output
,
result
=
s
.
handleClientMessage
(
token
,
noun
,
method
,
headers
,
message
)
}
else
{
status
,
output
=
s
.
handleRevocationMessage
(
noun
,
method
,
args
,
headers
,
message
)
}
return
}
func
(
s
*
Server
)
handleClientMessage
(
token
,
noun
,
method
string
,
headers
map
[
string
][]
string
,
message
[]
byte
,
)
(
status
int
,
output
[]
byte
,
result
*
server
.
SessionResult
)
{
// Fetch the session
session
:=
s
.
sessions
.
clientGet
(
token
)
if
session
==
nil
{
...
...
@@ -498,3 +519,67 @@ func (s *Server) handleProtocolMessage(
return
}
}
func
(
s
*
Server
)
handleRevocationMessage
(
noun
,
method
string
,
args
[]
string
,
headers
map
[
string
][]
string
,
message
[]
byte
,
)
(
int
,
[]
byte
)
{
if
noun
==
"records"
&&
method
==
http
.
MethodGet
{
if
len
(
args
)
!=
2
{
return
server
.
JsonResponse
(
nil
,
server
.
RemoteError
(
server
.
ErrorInvalidRequest
,
"GET records expects 2 url arguments"
))
}
index
,
err
:=
strconv
.
Atoi
(
args
[
1
])
if
err
!=
nil
{
return
server
.
JsonResponse
(
nil
,
server
.
RemoteError
(
server
.
ErrorMalformedInput
,
err
.
Error
()))
}
cred
:=
irma
.
NewCredentialTypeIdentifier
(
args
[
0
])
return
server
.
JsonResponse
(
s
.
handleGetRevocationRecords
(
cred
,
index
))
}
if
noun
==
"records"
&&
method
==
http
.
MethodPost
{
if
len
(
args
)
!=
1
{
return
server
.
JsonResponse
(
nil
,
server
.
RemoteError
(
server
.
ErrorInvalidRequest
,
"POST records expects 1 url arguments"
))
}
cred
:=
irma
.
NewCredentialTypeIdentifier
(
args
[
0
])
var
records
[]
*
revocation
.
Record
if
err
:=
json
.
Unmarshal
(
message
,
&
records
);
err
!=
nil
{
return
server
.
JsonResponse
(
nil
,
server
.
RemoteError
(
server
.
ErrorMalformedInput
,
err
.
Error
()))
}
return
server
.
JsonResponse
(
s
.
handlePostRevocationRecords
(
cred
,
records
))
}
return
server
.
JsonResponse
(
nil
,
server
.
RemoteError
(
server
.
ErrorInvalidRequest
,
""
))
}
func
(
s
*
Server
)
handlePostRevocationRecords
(
cred
irma
.
CredentialTypeIdentifier
,
records
[]
*
revocation
.
Record
,
)
(
interface
{},
*
irma
.
RemoteError
)
{
if
_
,
ok
:=
s
.
conf
.
RevocableCredentials
[
cred
];
!
ok
{
return
nil
,
server
.
RemoteError
(
server
.
ErrorInvalidRequest
,
"not supported by this server"
)
}
db
,
err
:=
s
.
conf
.
IrmaConfiguration
.
RevocationDB
(
cred
)
if
err
!=
nil
{
return
nil
,
server
.
RemoteError
(
server
.
ErrorUnknown
,
err
.
Error
())
// TODO error type
}
for
_
,
r
:=
range
records
{
if
err
=
db
.
Add
(
r
.
Message
,
r
.
PublicKeyIndex
);
err
!=
nil
{
return
nil
,
server
.
RemoteError
(
server
.
ErrorUnknown
,
err
.
Error
())
// TODO error type
}
}
return
nil
,
nil
}
func
(
s
*
Server
)
handleGetRevocationRecords
(
cred
irma
.
CredentialTypeIdentifier
,
index
int
,
)
([]
revocation
.
Record
,
*
irma
.
RemoteError
)
{
if
_
,
ok
:=
s
.
conf
.
RevocableCredentials
[
cred
];
!
ok
{
return
nil
,
server
.
RemoteError
(
server
.
ErrorInvalidRequest
,
"not supported by this server"
)
}
db
,
err
:=
s
.
conf
.
IrmaConfiguration
.
RevocationDB
(
cred
)
if
err
!=
nil
{
return
nil
,
server
.
RemoteError
(
server
.
ErrorUnknown
,
err
.
Error
())
// TODO error type
}
records
,
err
:=
db
.
RevocationRecords
(
index
)
if
err
!=
nil
{
return
nil
,
server
.
RemoteError
(
server
.
ErrorUnknown
,
err
.
Error
())
// TODO error type
}
return
records
,
nil
}
server/api.go
View file @
8d0c0554
package
server
import
(
"bytes"
"encoding/gob"
"encoding/json"
"fmt"
"io/ioutil"
...
...
@@ -40,6 +42,8 @@ type Configuration struct {
IssuerPrivateKeys
map
[
irma
.
IssuerIdentifier
]
*
gabi
.
PrivateKey
`json:"-"`
// Path at which to store revocation databases
RevocationPath
string
`json:"revocation_path" mapstructure:"revocation_path"`
// Credentials types for which revocation database should be hosted
RevocableCredentials
map
[
irma
.
CredentialTypeIdentifier
]
struct
{}
`json:"-"`
// URL at which the IRMA app can reach this server during sessions
URL
string
`json:"url" mapstructure:"url"`
// Required to be set to true if URL does not begin with https:// in production mode.
...
...
@@ -170,13 +174,29 @@ func RemoteError(err Error, message string) *irma.RemoteError {
// JsonResponse JSON-marshals the specified object or error
// and returns it along with a suitable HTTP status code
func
JsonResponse
(
v
interface
{},
err
*
irma
.
RemoteError
)
(
int
,
[]
byte
)
{
return
encodeValOrError
(
v
,
err
,
json
.
Marshal
)
}
func
GobResponse
(
v
interface
{},
err
*
irma
.
RemoteError
)
(
int
,
[]
byte
)
{
return
encodeValOrError
(
v
,
err
,
gobMarshal
)
}
func
gobMarshal
(
v
interface
{})
([]
byte
,
error
)
{
var
b
bytes
.
Buffer
if
err
:=
gob
.
NewEncoder
(
&
b
)
.
Encode
(
v
);
err
!=
nil
{
return
nil
,
err
}
return
b
.
Bytes
(),
nil
}
func
encodeValOrError
(
v
interface
{},
err
*
irma
.
RemoteError
,
encoder
func
(
interface
{})
([]
byte
,
error
))
(
int
,
[]
byte
)
{
msg
:=
v
status
:=
http
.
StatusOK
if
err
!=
nil
{
msg
=
err
status
=
err
.
Status
}
b
,
e
:=
json
.
Marshal
(
msg
)
b
,
e
:=
encoder
(
msg
)
if
e
!=
nil
{
Logger
.
Error
(
"Failed to serialize response:"
,
e
.
Error
())
return
http
.
StatusInternalServerError
,
nil
...
...
server/irmaserver/main.go
View file @
8d0c0554
...
...
@@ -126,8 +126,8 @@ func (s *Server) HandlerFunc() http.HandlerFunc {
}
}
token
,
noun
,
err
:=
servercore
.
ParsePath
(
r
.
URL
.
Path
)
if
err
==
nil
&&
noun
==
"statusevents"
{
// if err != nil we let it be handled by HandleProtocolMessage below
token
,
noun
,
_
,
err
:=
servercore
.
ParsePath
(
r
.
URL
.
Path
)
if
err
==
nil
&&
token
!=
""
&&
noun
==
"statusevents"
{
// if err != nil we let it be handled by HandleProtocolMessage below
if
err
=
s
.
SubscribeServerSentEvents
(
w
,
r
,
token
,
false
);
err
!=
nil
{
server
.
WriteResponse
(
w
,
nil
,
&
irma
.
RemoteError
{
Status
:
server
.
ErrorUnsupported
.
Status
,
...
...
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