@ -3,6 +3,7 @@ package acme
import (
"context"
"crypto"
"crypto/ed25519"
"encoding/base64"
"encoding/json"
"encoding/pem"
@ -45,8 +46,21 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
}
} ,
"fail/no-linker" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
return test {
ctx : ctx ,
expectedErr : & Error {
Type : "urn:ietf:params:acme:error:serverInternal" ,
Detail : "The server experienced an internal error" ,
Status : 500 ,
Err : errors . New ( "missing linker" ) ,
} ,
}
} ,
"fail/unmarshal" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ctx : ctx ,
payload : [ ] byte ( "?!" ) ,
@ -69,6 +83,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
"fail/wire-parse-id" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ctx : ctx ,
payload : [ ] byte ( "{}" ) ,
@ -91,6 +106,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
"fail/wire-parse-client-id" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
valueBytes , err := json . Marshal ( struct {
Name string ` json:"name,omitempty" `
Domain string ` json:"domain,omitempty" `
@ -125,6 +141,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
"fail/no-wire-options" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
valueBytes , err := json . Marshal ( struct {
Name string ` json:"name,omitempty" `
Domain string ` json:"domain,omitempty" `
@ -162,7 +179,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Wire : & wireprovisioner . Options {
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://issuerexample.com" ,
IssuerURL : "http://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
@ -177,6 +195,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
valueBytes , err := json . Marshal ( struct {
Name string ` json:"name,omitempty" `
Domain string ` json:"domain,omitempty" `
@ -248,12 +267,17 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Challenge string ` json:"chal,omitempty" `
Handle string ` json:"handle,omitempty" `
Nonce string ` json:"nonce,omitempty" `
HTU string ` json:"htu,omitempty" `
} {
Claims : jose . Claims {
Subject : "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com" ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID" } ,
} ,
Challenge : "token" ,
Handle : "wireapp://%40alice_wire@wire.com" ,
Nonce : "nonce" ,
HTU : "http://issuer.example.com" ,
} )
require . NoError ( t , err )
dpop , err := dpopSigner . Sign ( dpopBytes )
@ -263,6 +287,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
tokenBytes , err := json . Marshal ( struct {
jose . Claims
Challenge string ` json:"chal,omitempty" `
Nonce string ` json:"nonce,omitempty" `
Cnf struct {
Kid string ` json:"kid,omitempty" `
} ` json:"cnf" `
@ -273,10 +298,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} {
Claims : jose . Claims {
Issuer : "http://issuer.example.com" ,
Audience : [ ] string { "test "} ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID "} ,
Expiry : jose . NewNumericDate ( time . Now ( ) . Add ( 1 * time . Minute ) ) ,
} ,
Challenge : "token" ,
Nonce : "nonce" ,
Cnf : struct {
Kid string ` json:"kid,omitempty" `
} {
@ -315,7 +341,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Wire : & wireprovisioner . Options {
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://issuerexample.com" ,
IssuerURL : "http://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
@ -325,10 +352,12 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
TransformTemplate : "" ,
} ,
DPOP : & wireprovisioner . DPOPOptions {
Target : "http://issuer.example.com" ,
SigningKey : signerPEMBytes ,
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -382,12 +411,17 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Challenge string ` json:"chal,omitempty" `
Handle string ` json:"handle,omitempty" `
Nonce string ` json:"nonce,omitempty" `
HTU string ` json:"htu,omitempty" `
} {
Claims : jose . Claims {
Subject : "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com" ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID" } ,
} ,
Challenge : "token" ,
Handle : "wireapp://%40alice_wire@wire.com" ,
Nonce : "nonce" ,
HTU : "http://issuer.example.com" ,
} )
require . NoError ( t , err )
dpop , err := dpopSigner . Sign ( dpopBytes )
@ -397,6 +431,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
tokenBytes , err := json . Marshal ( struct {
jose . Claims
Challenge string ` json:"chal,omitempty" `
Nonce string ` json:"nonce,omitempty" `
Cnf struct {
Kid string ` json:"kid,omitempty" `
} ` json:"cnf" `
@ -407,10 +442,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} {
Claims : jose . Claims {
Issuer : "http://issuer.example.com" ,
Audience : [ ] string { "test "} ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID "} ,
Expiry : jose . NewNumericDate ( time . Now ( ) . Add ( 1 * time . Minute ) ) ,
} ,
Challenge : "token" ,
Nonce : "nonce" ,
Cnf : struct {
Kid string ` json:"kid,omitempty" `
} {
@ -449,24 +485,23 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Wire : & wireprovisioner . Options {
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://issuerexample.com" ,
IssuerURL : "http://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
} ,
DPOP : & wireprovisioner . DPOPOptions {
Target : "http://issuer.example.com" ,
SigningKey : signerPEMBytes ,
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -524,12 +559,17 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Challenge string ` json:"chal,omitempty" `
Handle string ` json:"handle,omitempty" `
Nonce string ` json:"nonce,omitempty" `
HTU string ` json:"htu,omitempty" `
} {
Claims : jose . Claims {
Subject : "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com" ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID" } ,
} ,
Challenge : "token" ,
Handle : "wireapp://%40alice_wire@wire.com" ,
Nonce : "nonce" ,
HTU : "http://issuer.example.com" ,
} )
require . NoError ( t , err )
dpop , err := dpopSigner . Sign ( dpopBytes )
@ -539,6 +579,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
tokenBytes , err := json . Marshal ( struct {
jose . Claims
Challenge string ` json:"chal,omitempty" `
Nonce string ` json:"nonce,omitempty" `
Cnf struct {
Kid string ` json:"kid,omitempty" `
} ` json:"cnf" `
@ -549,10 +590,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} {
Claims : jose . Claims {
Issuer : "http://issuer.example.com" ,
Audience : [ ] string { "test "} ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID "} ,
Expiry : jose . NewNumericDate ( time . Now ( ) . Add ( 1 * time . Minute ) ) ,
} ,
Challenge : "token" ,
Nonce : "nonce" ,
Cnf : struct {
Kid string ` json:"kid,omitempty" `
} {
@ -591,24 +633,23 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Wire : & wireprovisioner . Options {
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://issuerexample.com" ,
IssuerURL : "http://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
} ,
DPOP : & wireprovisioner . DPOPOptions {
Target : "http://issuer.example.com" ,
SigningKey : signerPEMBytes ,
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -666,12 +707,17 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Challenge string ` json:"chal,omitempty" `
Handle string ` json:"handle,omitempty" `
Nonce string ` json:"nonce,omitempty" `
HTU string ` json:"htu,omitempty" `
} {
Claims : jose . Claims {
Subject : "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com" ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID" } ,
} ,
Challenge : "token" ,
Handle : "wireapp://%40alice_wire@wire.com" ,
Nonce : "nonce" ,
HTU : "http://issuer.example.com" ,
} )
require . NoError ( t , err )
dpop , err := dpopSigner . Sign ( dpopBytes )
@ -681,6 +727,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
tokenBytes , err := json . Marshal ( struct {
jose . Claims
Challenge string ` json:"chal,omitempty" `
Nonce string ` json:"nonce,omitempty" `
Cnf struct {
Kid string ` json:"kid,omitempty" `
} ` json:"cnf" `
@ -691,10 +738,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} {
Claims : jose . Claims {
Issuer : "http://issuer.example.com" ,
Audience : [ ] string { "test "} ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID "} ,
Expiry : jose . NewNumericDate ( time . Now ( ) . Add ( 1 * time . Minute ) ) ,
} ,
Challenge : "token" ,
Nonce : "nonce" ,
Cnf : struct {
Kid string ` json:"kid,omitempty" `
} {
@ -733,24 +781,23 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Wire : & wireprovisioner . Options {
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://issuerexample.com" ,
IssuerURL : "http://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
} ,
DPOP : & wireprovisioner . DPOPOptions {
Target : "http://issuer.example.com" ,
SigningKey : signerPEMBytes ,
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -815,12 +862,17 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Challenge string ` json:"chal,omitempty" `
Handle string ` json:"handle,omitempty" `
Nonce string ` json:"nonce,omitempty" `
HTU string ` json:"htu,omitempty" `
} {
Claims : jose . Claims {
Subject : "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com" ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID" } ,
} ,
Challenge : "token" ,
Handle : "wireapp://%40alice_wire@wire.com" ,
Nonce : "nonce" ,
HTU : "http://issuer.example.com" ,
} )
require . NoError ( t , err )
dpop , err := dpopSigner . Sign ( dpopBytes )
@ -830,6 +882,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
tokenBytes , err := json . Marshal ( struct {
jose . Claims
Challenge string ` json:"chal,omitempty" `
Nonce string ` json:"nonce,omitempty" `
Cnf struct {
Kid string ` json:"kid,omitempty" `
} ` json:"cnf" `
@ -840,10 +893,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} {
Claims : jose . Claims {
Issuer : "http://issuer.example.com" ,
Audience : [ ] string { "test "} ,
Audience : jose . Audience { "https://ca.example.com/acme/wire/challenge/azID/chID "} ,
Expiry : jose . NewNumericDate ( time . Now ( ) . Add ( 1 * time . Minute ) ) ,
} ,
Challenge : "token" ,
Nonce : "nonce" ,
Cnf : struct {
Kid string ` json:"kid,omitempty" `
} {
@ -854,7 +908,6 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
APIVersion : 5 ,
Scope : "wire_client_id" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
require . NoError ( t , err )
@ -882,24 +935,23 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Wire : & wireprovisioner . Options {
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://issuerexample.com" ,
IssuerURL : "http://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
} ,
DPOP : & wireprovisioner . DPOPOptions {
Target : "http://issuer.example.com" ,
SigningKey : signerPEMBytes ,
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -984,8 +1036,21 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
}
} ,
"fail/no-linker" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
return test {
ctx : ctx ,
expectedErr : & Error {
Type : "urn:ietf:params:acme:error:serverInternal" ,
Detail : "The server experienced an internal error" ,
Status : 500 ,
Err : errors . New ( "missing linker" ) ,
} ,
}
} ,
"fail/unmarshal" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ctx : ctx ,
payload : [ ] byte ( "?!" ) ,
@ -1014,6 +1079,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
"fail/wire-parse-id" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ctx : ctx ,
payload : [ ] byte ( "{}" ) ,
@ -1036,6 +1102,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
"fail/no-wire-options" : func ( t * testing . T ) test {
ctx := NewProvisionerContext ( context . Background ( ) , newWireProvisionerWithOptions ( t , & provisioner . Options { } ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
valueBytes , err := json . Marshal ( struct {
Name string ` json:"name,omitempty" `
Domain string ` json:"domain,omitempty" `
@ -1068,14 +1135,44 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
}
} ,
"fail/keyauth-mismatch" : func ( t * testing . T ) test {
jwk , _ := mustAccountAndKeyAuthorization ( t , "token" )
"fail/verify" : func ( t * testing . T ) test {
jwk , keyAuth := mustAccountAndKeyAuthorization ( t , "token" )
signerJWK , err := jose . GenerateJWK ( "EC" , "P-256" , "ES256" , "sig" , "" , 0 )
require . NoError ( t , err )
signer , err := jose . NewSigner ( jose . SigningKey {
Algorithm : jose . SignatureAlgorithm ( signerJWK . Algorithm ) ,
Key : signerJWK ,
} , new ( jose . SignerOptions ) )
require . NoError ( t , err )
anotherSignerJWK , err := jose . GenerateJWK ( "EC" , "P-256" , "ES256" , "sig" , "" , 0 )
require . NoError ( t , err )
srv := mustJWKServer ( t , anotherSignerJWK . Public ( ) )
tokenBytes , err := json . Marshal ( struct {
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
Audience : [ ] string { "test" } ,
Expiry : jose . NewNumericDate ( time . Now ( ) . Add ( 1 * time . Minute ) ) ,
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40alice_wire@wire.com" ,
KeyAuth : keyAuth ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
require . NoError ( t , err )
idToken , err := signed . CompactSerialize ( )
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : "some-token" ,
KeyAuth : "wrong-key-authorization" ,
IDToken : idToken ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1094,7 +1191,9 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Wire : & wireprovisioner . Options {
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://issuer.example.com" ,
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
@ -1108,6 +1207,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1118,6 +1218,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Status : StatusPending ,
Value : string ( valueBytes ) ,
} ,
srv : srv ,
payload : payload ,
ctx : ctx ,
jwk : jwk ,
@ -1134,7 +1235,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
assert . Equal ( t , "urn:ietf:params:acme:error:rejectedIdentifier" , k . Type )
assert . Equal ( t , "The server will not issue certificates for the identifier" , k . Detail )
assert . Equal ( t , 400 , k . Status )
assert . Contains( t , k . Err . Error ( ) , ` keyAuthorization does not match; expected ` )
assert . Equal( t , ` error verifying ID token signature: failed to verify signature: failed to verify id token signature ` , k . Err . Error ( ) )
}
}
return nil
@ -1142,8 +1243,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
}
} ,
"fail/ verify ": func ( t * testing . T ) test {
jwk , keyAuth := mustAccountAndKeyAuthorization ( t , "token" )
"fail/ keyauth-mismatch ": func ( t * testing . T ) test {
jwk , _ := mustAccountAndKeyAuthorization ( t , "token" )
signerJWK , err := jose . GenerateJWK ( "EC" , "P-256" , "ES256" , "sig" , "" , 0 )
require . NoError ( t , err )
signer , err := jose . NewSigner ( jose . SigningKey {
@ -1151,13 +1252,13 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Key : signerJWK ,
} , new ( jose . SignerOptions ) )
require . NoError ( t , err )
anotherSignerJWK , err := jose . GenerateJWK ( "EC" , "P-256" , "ES256" , "sig" , "" , 0 )
require . NoError ( t , err )
srv := mustJWKServer ( t , anotherSignerJWK . Public ( ) )
srv := mustJWKServer ( t , signerJWK . Public ( ) )
tokenBytes , err := json . Marshal ( struct {
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
@ -1166,6 +1267,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40alice_wire@wire.com" ,
KeyAuth : "wrong-keyauth" ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
@ -1174,10 +1277,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : idToken ,
KeyAuth : keyAuth ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1198,14 +1299,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Provider : & wireprovisioner . Provider {
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
@ -1215,6 +1313,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1242,7 +1341,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
assert . Equal ( t , "urn:ietf:params:acme:error:rejectedIdentifier" , k . Type )
assert . Equal ( t , "The server will not issue certificates for the identifier" , k . Detail )
assert . Equal ( t , 400 , k . Status )
assert . Equal( t , ` error verifying ID token signature: failed to verify signature: failed to verify id token signature ` , k . Err . Error ( ) )
assert . Contains( t , k . Err . Error ( ) , "keyAuthorization does not match" )
}
}
return nil
@ -1264,6 +1363,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
@ -1272,6 +1373,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40bob@wire.com" ,
KeyAuth : keyAuth ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
@ -1280,10 +1383,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : idToken ,
KeyAuth : keyAuth ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1304,14 +1405,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Provider : & wireprovisioner . Provider {
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
@ -1321,6 +1419,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1348,7 +1447,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
assert . Equal ( t , "urn:ietf:params:acme:error:rejectedIdentifier" , k . Type )
assert . Equal ( t , "The server will not issue certificates for the identifier" , k . Detail )
assert . Equal ( t , 400 , k . Status )
assert . Equal ( t , ` claims in OIDC ID token don't match: invalid ' handl e' "wireapp://%40bob@wire.com" after transformation` , k . Err . Error ( ) )
assert . Equal ( t , ` claims in OIDC ID token don't match: invalid ' preferred_usernam e' "wireapp://%40bob@wire.com" after transformation` , k . Err . Error ( ) )
}
}
return nil
@ -1370,6 +1469,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
@ -1378,6 +1479,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40alice_wire@wire.com" ,
KeyAuth : keyAuth ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
@ -1386,10 +1489,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : idToken ,
KeyAuth : keyAuth ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1410,14 +1511,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Provider : & wireprovisioner . Provider {
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
@ -1427,6 +1525,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1473,6 +1572,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
@ -1481,6 +1582,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40alice_wire@wire.com" ,
KeyAuth : keyAuth ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
@ -1489,10 +1592,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : idToken ,
KeyAuth : keyAuth ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1513,14 +1614,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Provider : & wireprovisioner . Provider {
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
@ -1530,6 +1628,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1580,6 +1679,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
@ -1588,6 +1689,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40alice_wire@wire.com" ,
KeyAuth : keyAuth ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
@ -1596,10 +1699,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : idToken ,
KeyAuth : keyAuth ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1620,14 +1721,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Provider : & wireprovisioner . Provider {
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
@ -1637,6 +1735,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1687,6 +1786,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
@ -1695,6 +1796,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40alice_wire@wire.com" ,
KeyAuth : keyAuth ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
@ -1703,10 +1806,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : idToken ,
KeyAuth : keyAuth ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1727,14 +1828,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Provider : & wireprovisioner . Provider {
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
@ -1744,6 +1842,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1774,7 +1873,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
MockCreateOidcToken : func ( ctx context . Context , orderID string , idToken map [ string ] interface { } ) error {
assert . Equal ( t , "orderID" , orderID )
assert . Equal ( t , "Alice Smith" , idToken [ "name" ] . ( string ) )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , idToken [ " handl e"] . ( string ) )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , idToken [ " preferred_usernam e"] . ( string ) )
return errors . New ( "fail" )
} ,
} ,
@ -1800,6 +1899,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
jose . Claims
Name string ` json:"name,omitempty" `
PreferredUsername string ` json:"preferred_username,omitempty" `
KeyAuth string ` json:"keyauth" `
ACMEAudience string ` json:"acme_aud" `
} {
Claims : jose . Claims {
Issuer : srv . URL ,
@ -1808,6 +1909,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
Name : "Alice Smith" ,
PreferredUsername : "wireapp://%40alice_wire@wire.com" ,
KeyAuth : keyAuth ,
ACMEAudience : "https://ca.example.com/acme/wire/challenge/azID/chID" ,
} )
require . NoError ( t , err )
signed , err := signer . Sign ( tokenBytes )
@ -1816,10 +1919,8 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
require . NoError ( t , err )
payload , err := json . Marshal ( struct {
IDToken string ` json:"id_token" `
KeyAuth string ` json:"keyauth" `
} {
IDToken : idToken ,
KeyAuth : keyAuth ,
} )
require . NoError ( t , err )
valueBytes , err := json . Marshal ( struct {
@ -1840,14 +1941,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
Provider : & wireprovisioner . Provider {
IssuerURL : srv . URL ,
JWKSURL : srv . URL + "/keys" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
SkipClientIDCheck : false ,
SkipExpiryCheck : false ,
SkipIssuerCheck : false ,
InsecureSkipSignatureCheck : false ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
@ -1857,6 +1955,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
} ,
} ,
} ) )
ctx = NewLinkerContext ( ctx , NewLinker ( "ca.example.com" , "acme" ) )
return test {
ch : & Challenge {
ID : "chID" ,
@ -1887,7 +1986,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
MockCreateOidcToken : func ( ctx context . Context , orderID string , idToken map [ string ] interface { } ) error {
assert . Equal ( t , "orderID" , orderID )
assert . Equal ( t , "Alice Smith" , idToken [ "name" ] . ( string ) )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , idToken [ " handl e"] . ( string ) )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , idToken [ " preferred_usernam e"] . ( string ) )
return nil
} ,
} ,
@ -1920,19 +2019,23 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
}
func Test_parseAndVerifyWireAccessToken ( t * testing . T ) {
t . Skip ( "skip until we can retrieve public key from e2e test, so that we can actually verify the token" )
key := `
-- -- - BEGIN PUBLIC KEY -- -- -
MCowBQYDK2VwAyEAB2IYqBWXAouDt3WcCZgCM3t9gumMEKMlgMsGenSu + fA =
-- -- - END PUBLIC KEY -- -- - `
publicKey , err := pemutil . Parse ( [ ] byte ( key ) )
require . NoError ( t , err )
pk , ok := publicKey . ( ed25519 . PublicKey )
require . True ( t , ok )
issuer := "http://wire.com:19983/clients/7a41cf5b79683410/access-token"
wireID := wire . ID {
ClientID : "wireapp://guVX5xeFS3eTatmXBIyA4A!7a41cf5b79683410@wire.com" ,
Handle : "wireapp://%40alice_wire@wire.com" ,
}
token := ` eyJhbGciOiJFZERTQSIsInR5cCI6ImF0K2p3dCIsImp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6I kIySVlxQldYQW91RHQzV2NDWmdDTTN0OWd1bU1FS01sZ01zR2VuU3UtZkEifX0.eyJpYXQiOjE3MDQ5ODUyMDUsImV4cCI6MTcwNDk4OTE2NSwibmJmIjoxNzA0OTg1MjA1LCJpc3MiOiJodHRwOi8vd2lyZS5jb206MTk5ODMvY2xpZW50cy83YTQxY2Y1Yjc5NjgzNDEwL2FjY2Vzcy10b2tlbiIsInN1YiI6IndpcmVhcHA6Ly9ndVZYNXhlRlMzZVRhdG1YQkl5QTRBITdhNDFjZjViNzk2ODM0MTBAd2lyZS5jb20iLCJhdWQiOiJodHRwOi8vd2lyZS5jb206MTk5ODMvY2xpZW50cy83YTQxY2Y1Yjc5NjgzNDEwL2FjY2Vzcy10b2tlbiIsImp0aSI6IjQyYzQ2ZDRjLWU1MTAtNDE3NS05ZmI1LWQwNTVlMTI1YTQ5ZCIsIm5vbmNlIjoiVUVKeVIyZHFPRWh6WkZKRVlXSkJhVGt5T0RORVlURTJhRXMwZEhJeGNFYyIsImNoYWwiOiJiWFVHTnBVZmNSeDNFaEIzNHhQM3k2MmFRWm9HWlM2aiIsImNuZiI6eyJraWQiOiJvTVdmTkRKUXNJNWNQbFhONVVvQk5uY0t0YzRmMmRxMnZ3Q2pqWHNxdzdR In0sInByb29mIjoiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNkltUndiM0FyYW5kMElpd2lhbmRySWpwN0ltdDBlU0k2SWs5TFVDSXNJbU55ZGlJNklrVmtNalUxTVRraUxDSjRJam9pTVV3eFpVZ3lZVFpCWjFaMmVsUndOVnBoYkV0U1puRTJjRlpRVDNSRmFrazNhRGhVVUhwQ1dVWm5UU0o5ZlEuZXlKcFlYUWlPakUzTURRNU9EVXlNRFVzSW1WNGNDSTZNVGN3TkRrNU1qUXdOU3dpYm1KbUlqb3hOekEwT1RnMU1qQTFMQ0p6ZFdJaU9pSjNhWEpsWVhCd09pOHZaM1ZXV0RWNFpVWlRNMlZVWVhSdFdFSkplVUUwUVNFM1lUUXhZMlkxWWpjNU5qZ3pOREV3UUhkcGNtVXVZMjl0SWl3aWFuUnBJam9pTldVMk5qZzBZMkl0Tm1JME9DMDBOamhrTFdJd09URXRabVl3TkdKbFpEWmxZekpsSWl3aWJtOXVZMlVpT2lKVlJVcDVVakprY1U5RmFIcGFSa3BGV1ZkS1FtRlVhM2xQUkU1RldWUkZNbUZGY3pCa1NFbDRZMFZqSWl3aWFIUnRJam9pVUU5VFZDSXNJbWgwZFNJNkltaDBkSEE2THk5M2FYSmxMbU52YlRveE9UazRNeTlqYkdsbGJuUnpMemRoTkRGalpqVmlOemsyT0RNME1UQXZZV05qWlhOekxYUnZhMlZ1SWl3aVkyaGhiQ0k2SW1KWVZVZE9jRlZtWTFKNE0wVm9Rak0wZUZBemVUWXlZVkZhYjBkYVV6WnFJaXdpYUdGdVpHeGxJam9pZDJseVpXRndjRG92THlVME1HRnNhV05sWDNkcGNtVkFkMmx5WlM1amIyMGlMQ0owWldGdElqb2lkMmx5WlNKOS52bkN1T2JURFRLVFhCYXpyX3Z2X0xyZDBZT1Rac2xteHQtM2xKNWZKSU9iRVRidUVCTGlEaS1JVWZHcFJHTm1Dbm9IZjVocHNsWW5HeFMzSjloUmVDZyIsImNsaWVudF9pZCI6IndpcmVhcHA6Ly9ndVZYNXhlRlMzZVRhdG1YQkl5QTRBITdhNDFjZjViNzk2ODM0MTBAd2lyZS5jb20iLCJhcGlfdmVyc2lvbiI6NSwic2NvcGUiOiJ3aXJlX2NsaWVudF9pZCJ9.uCVYhmvCJm7nM1NxJQKl_XZJcSqm9eFmNmbRJkA5Wpsw70ZF1YANYC9nQ91QgsnuAbaRZMJiJt3P8ZntR2ozDQ `
token := ` eyJhbGciOiJFZERTQSIsInR5cCI6ImF0K2p3dCIsImp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6I m8zcWZhQ045a2FzSnZJRlhPdFNMTGhlYW0wTE5jcVF5MHdBMk9PeFRRNW8ifX0.eyJpYXQiOjE3MDU0OTc3MzksImV4cCI6MTcwNTUwMTY5OSwibmJmIjoxNzA1NDk3NzM5LCJpc3MiOiJodHRwOi8vd2lyZS5jb206MTY4MjQvY2xpZW50cy8zN2ZlOThiZDQwZDBkZmUvYWNjZXNzLXRva2VuIiwic3ViIjoid2lyZWFwcDovLzE4NXdIUmtRVHdTOTVGODhaZTQ1SlEhMzdmZTk4YmQ0MGQwZGZlQHdpcmUuY29tIiwiYXVkIjoiaHR0cHM6Ly9zdGVwY2E6NTUwMjMvYWNtZS93aXJlL2NoYWxsZW5nZS9SeEdSWGVoRGxCcHcxNTJQTVUzem0xY2M0cEtGcHVWRi9RWnRFazdQNUVFRXhadHBSYngydjVoYlc3QXB1S2NOSSIsImp0aSI6ImU1MzllODYzLTRkNTgtNGMwMS1iYjk3LTYwODdiNTEzOWIyMCIsIm5vbmNlIjoiUzJKYWVWcExkV28wUkZKaFFrWndXR0ZKY0VoVlFrNUxXVGd4WkhkRFVqQSIsImNoYWwiOiIyaDFPdUdxbTBKUXd6bHVsWGtLSTJEMGZiRDgzRUIxdyIsImNuZiI6eyJraWQiOiJhSEY3MVhYeG0tTWE5Q05zSjNaU1RKTjlYS0ZxOFFmOGh2UTJLN3NLQmQ4 In0sInByb29mIjoiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNkltUndiM0FyYW5kMElpd2lhbmRySWpwN0ltdDBlU0k2SWs5TFVDSXNJbU55ZGlJNklrVmtNalUxTVRraUxDSjRJam9pWVVsaVMwcFBha0poWXpZeVF6TnRhVmhHVjAxb09ITTJkRXQzUkROaGNHRnVSMHBQZURaVVFYVklRU0o5ZlEuZXlKcFlYUWlPakUzTURVME9UYzNNemtzSW1WNGNDSTZNVGN3TlRVd05Ea3pPU3dpYm1KbUlqb3hOekExTkRrM056TTVMQ0p6ZFdJaU9pSjNhWEpsWVhCd09pOHZNVGcxZDBoU2ExRlVkMU01TlVZNE9GcGxORFZLVVNFek4yWmxPVGhpWkRRd1pEQmtabVZBZDJseVpTNWpiMjBpTENKaGRXUWlPaUpvZEhSd2N6b3ZMM04wWlhCallUbzFOVEF5TXk5aFkyMWxMM2RwY21VdlkyaGhiR3hsYm1kbEwxSjRSMUpZWldoRWJFSndkekUxTWxCTlZUTjZiVEZqWXpSd1MwWndkVlpHTDFGYWRFVnJOMUExUlVWRmVGcDBjRkppZURKMk5XaGlWemRCY0hWTFkwNUpJaXdpYW5ScElqb2lNV1kxTUdRM1lUQXRaamt6WmkwME5XWXdMV0V3TWpBdE1ETm1NREJpTlRreVlUUmtJaXdpYm05dVkyVWlPaUpUTWtwaFpWWndUR1JYYnpCU1JrcG9VV3RhZDFkSFJrcGpSV2hXVVdzMVRGZFVaM2hhU0dSRVZXcEJJaXdpYUhSdElqb2lVRTlUVkNJc0ltaDBkU0k2SW1oMGRIQTZMeTkzYVhKbExtTnZiVG94TmpneU5DOWpiR2xsYm5Sekx6TTNabVU1T0dKa05EQmtNR1JtWlM5aFkyTmxjM010ZEc5clpXNGlMQ0pqYUdGc0lqb2lNbWd4VDNWSGNXMHdTbEYzZW14MWJGaHJTMGt5UkRCbVlrUTRNMFZDTVhjaUxDSm9ZVzVrYkdVaU9pSjNhWEpsWVhCd09pOHZKVFF3WVd4cFkyVmZkMmx5WlVCM2FYSmxMbU52YlNJc0luUmxZVzBpT2lKM2FYSmxJbjAuZlNmQnFuWWlfMTRhZEc5MDAyZ0RJdEgybXNyYW55eXVnR0g5bHpFcmprdmRGbkRPOFRVWWRYUXJKUzdlX3BlU0lzcGxlRUVkaGhzc0gwM3FBWHY2QXciLCJjbGllbnRfaWQiOiJ3aXJlYXBwOi8vMTg1d0hSa1FUd1M5NUY4OFplNDVKUSEzN2ZlOThiZDQwZDBkZmVAd2lyZS5jb20iLCJhcGlfdmVyc2lvbiI6NSwic2NvcGUiOiJ3aXJlX2NsaWVudF9pZCJ9.GKK7ZsJ8EWJjeaHqf8P48H9mluJhxyXUmI0FO3xstda3XDJIK7Z5Ur4hi1OIJB0ZsS5BqRVT2q5whL4KP9hZCA `
ch := & Challenge {
Token : "bXUGNpUfcRx3EhB34xP3y62aQZoGZS6j" ,
}
@ -1951,7 +2054,7 @@ MCowBQYDK2VwAyEAB2IYqBWXAouDt3WcCZgCM3t9gumMEKMlgMsGenSu+fA=
at , dpop , err := parseAndVerifyWireAccessToken ( wireVerifyParams {
token : token ,
tokenKey : p ublicKey ,
tokenKey : p k ,
dpopKey : accountJWK . Public ( ) ,
dpopKeyID : accountJWK . KeyID ,
issuer : issuer ,
@ -1959,6 +2062,7 @@ MCowBQYDK2VwAyEAB2IYqBWXAouDt3WcCZgCM3t9gumMEKMlgMsGenSu+fA=
chToken : ch . Token ,
t : issuedAt . Add ( 1 * time . Minute ) , // set validation time to be one minute after issuance
} )
if assert . NoError ( t , err ) {
// token assertions
assert . Equal ( t , "42c46d4c-e510-4175-9fb5-d055e125a49d" , at . ID )
@ -1995,15 +2099,17 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "http://dex:15818/dex" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "wireapp" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
Now : func ( ) time . Time {
return time . Date ( 2024 , 1 , 12 , 18 , 32 , 41 , 0 , time . UTC ) // (Token Expiry: 2024-01-12 21:32:42 +0100 CET)
} ,
InsecureSkipSignatureCheck : true ,
InsecureSkipSignatureCheck : true , // skipping signature check for this specific test
} ,
TransformTemplate : ` { "name": " {{ .preferred_username }} ", " handl e": "{{ .name }} "} ` ,
TransformTemplate : ` { "name": " {{ .preferred_username }} ", " preferred_usernam e": "{{ .name }} "} ` ,
} ,
DPOP : & wireprovisioner . DPOPOptions {
SigningKey : [ ] byte ( fakeKey ) ,
@ -2029,7 +2135,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
got , err := validateWireOIDCClaims ( o , idToken , wireID )
assert . NoError ( t , err )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , got [ " handl e"] . ( string ) )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , got [ " preferred_usernam e"] . ( string ) )
assert . Equal ( t , "Alice Smith" , got [ "name" ] . ( string ) )
assert . Equal ( t , "http://dex:15818/dex" , got [ "iss" ] . ( string ) )
}
@ -2044,9 +2150,11 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
OIDC : & wireprovisioner . OIDCOptions {
Provider : & wireprovisioner . Provider {
IssuerURL : "https://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wireprovisioner . Config {
ClientID : "unit test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
Now : time . Now ,
} ,
TransformTemplate : transformTemplate ,
@ -2090,18 +2198,18 @@ func Test_idTokenTransformation(t *testing.T) {
require . NoError ( t , err )
// default transformation sets preferred username to handle; name as name
assert . Equal ( t , "Alice Smith" , result [ " handl e"] . ( string ) )
assert . Equal ( t , "Alice Smith" , result [ " preferred_usernam e"] . ( string ) )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , result [ "name" ] . ( string ) )
assert . Equal ( t , "http://dex:15818/dex" , result [ "iss" ] . ( string ) )
// swap the preferred_name and the name
swap := ` { "name": " {{ .preferred_username }} ", " handl e": "{{ .name }} "} `
swap := ` { "name": " {{ .preferred_username }} ", " preferred_usernam e": "{{ .name }} "} `
opts = createWireOptions ( t , swap )
result , err = opts . GetOIDCOptions ( ) . Transform ( m )
require . NoError ( t , err )
// with the transformation, handle now contains wireapp://%40alice_wire@wire.com, name contains Alice Smith
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , result [ " handl e"] . ( string ) )
assert . Equal ( t , "wireapp://%40alice_wire@wire.com" , result [ " preferred_usernam e"] . ( string ) )
assert . Equal ( t , "Alice Smith" , result [ "name" ] . ( string ) )
assert . Equal ( t , "http://dex:15818/dex" , result [ "iss" ] . ( string ) )
}