@@ -19,6 +19,7 @@ import (
1919 "context"
2020 "crypto"
2121 "crypto/ecdsa"
22+ "crypto/ed25519"
2223 "crypto/sha256"
2324 "crypto/sha512"
2425 "crypto/x509"
@@ -260,15 +261,41 @@ func verifyOCISignature(ctx context.Context, verifier signature.Verifier, sig pa
260261 if err != nil {
261262 return err
262263 }
263- signature , err := base64 .StdEncoding .DecodeString (b64sig )
264+ decodedSignature , err := base64 .StdEncoding .DecodeString (b64sig )
264265 if err != nil {
265266 return err
266267 }
267268 payload , err := sig .Payload ()
268269 if err != nil {
269270 return err
270271 }
271- return verifier .VerifySignature (bytes .NewReader (signature ), bytes .NewReader (payload ), options .WithContext (ctx ))
272+ // For compatibility reasons, if ED25519ph is used, we try both ED25519 and ED25519ph.
273+ // Refusing to verify ED25519 signatures (used e.g. by rekord entries) would break compatibility.
274+ // The signature algorithm to use should be uniquely determined before this point.
275+ verificationErr := verifier .VerifySignature (bytes .NewReader (decodedSignature ), bytes .NewReader (payload ), options .WithContext (ctx ))
276+ if verificationErr == nil {
277+ return nil
278+ }
279+
280+ switch verifier .(type ) {
281+ case * signature.ED25519phVerifier :
282+ publicKey , err := verifier .PublicKey ()
283+ if err != nil {
284+ return err
285+ }
286+
287+ if edPublicKey , ok := publicKey .(ed25519.PublicKey ); ok {
288+ altVerifier , err := signature .LoadED25519Verifier (edPublicKey )
289+ if err != nil {
290+ return err
291+ }
292+
293+ fmt .Fprintf (os .Stderr , "Failed to verify signature with ED25519ph, falling back to ED25519 for backward compatibility.\n " )
294+ verificationErr = altVerifier .VerifySignature (bytes .NewReader (decodedSignature ), bytes .NewReader (payload ), options .WithContext (ctx ))
295+ }
296+ }
297+
298+ return verificationErr
272299}
273300
274301// ValidateAndUnpackCert creates a Verifier from a certificate. Verifies that the
0 commit comments