Repository: smallstep/crypto
Pull request #87 (2022-10-05 01:22:17)

[action] Remove gitleaks secret


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d781944..457da9c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -8,9 +8,6 @@ on:
     - "master"
   pull_request:
   workflow_call:
-    secrets:
-      GITLEAKS_LICENSE_KEY:
-        required: true
 
 concurrency:
   group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
diff --git a/README.md b/README.md
index e91f391..763c827 100644
--- a/README.md
+++ b/README.md
@@ -75,8 +75,3 @@ or just a YubiKey or an ssh-agent. On the cloud it supports:
 * [Amazon AWS KMS](https://aws.amazon.com/kms/)
 * [Google Cloud Key Management](https://cloud.google.com/security-key-management)
 * [Microsoft Azure Key Vault](https://azure.microsoft.com/en-us/services/key-vault/)
-
-### fingerprint
-
-Package `fingerprint` provides methods for creating and encoding X.509
-certificate, SSH certificate and SSH key fingerprints.
diff --git a/fingerprint/fingerprint.go b/fingerprint/fingerprint.go
deleted file mode 100644
index 6eb174b..0000000
--- a/fingerprint/fingerprint.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package fingerprint
-
-import (
-	"crypto"
-	"encoding/base64"
-	"encoding/hex"
-	"fmt"
-	"strings"
-
-	"go.step.sm/crypto/internal/emoji"
-)
-
-// Encoding defines the supported encodings for certificates and key
-// fingerprints.
-//
-// This type is the base for sshutil.FingerprintEncoding and
-// x509util.FingerprintEncoding types.
-type Encoding int
-
-const (
-	// HexFingerprint represents the hex encoding of the fingerprint.
-	//
-	// This is the default encoding for an X.509 certificate.
-	HexFingerprint Encoding = iota + 1
-	// Base64Fingerprint represents the base64 encoding of the fingerprint.
-	//
-	// This is the default encoding for a public key.
-	Base64Fingerprint
-	// Base64URLFingerprint represents the base64URL encoding of the fingerprint.
-	Base64URLFingerprint
-	// Base64RawFingerprint represents the base64RawStd encoding of the
-	// fingerprint.
-	//
-	// This is the default encoding for an SSH key and certificate.
-	Base64RawFingerprint
-	// Base64RawURLFingerprint represents the base64RawURL encoding of the fingerprint.
-	Base64RawURLFingerprint
-	// EmojiFingerprint represents the emoji encoding of the fingerprint.
-	EmojiFingerprint
-)
-
-// New creates a fingerprint of the given data by hashing it and returns it in
-// the encoding format.
-func New(data []byte, h crypto.Hash, encoding Encoding) (string, error) {
-	if !h.Available() {
-		return "", fmt.Errorf("hash function %q is not available", h.String())
-	}
-	hash := h.New()
-	if _, err := hash.Write(data); err != nil {
-		return "", fmt.Errorf("error creating hash: %w", err)
-	}
-	fp := Fingerprint(hash.Sum(nil), encoding)
-	if fp == "" {
-		return "", fmt.Errorf("unknown encoding value %d", encoding)
-	}
-	return fp, nil
-}
-
-// Fingerprint encodes the given digest using the encoding format. If an invalid
-// encoding is passed, the return value will be an empty string.
-func Fingerprint(digest []byte, encoding Encoding) string {
-	switch encoding {
-	case HexFingerprint:
-		return strings.ToLower(hex.EncodeToString(digest))
-	case Base64Fingerprint:
-		return base64.StdEncoding.EncodeToString(digest)
-	case Base64URLFingerprint:
-		return base64.URLEncoding.EncodeToString(digest)
-	case Base64RawFingerprint:
-		return base64.RawStdEncoding.EncodeToString(digest)
-	case Base64RawURLFingerprint:
-		return base64.RawURLEncoding.EncodeToString(digest)
-	case EmojiFingerprint:
-		return emoji.Emoji(digest)
-	default:
-		return ""
-	}
-}
diff --git a/internal/emoji/emoji.go b/internal/emoji/emoji.go
deleted file mode 100644
index 7235cff..0000000
--- a/internal/emoji/emoji.go
+++ /dev/null
@@ -1,274 +0,0 @@
-package emoji
-
-import "strings"
-
-func Emoji(input []byte) string {
-	var b strings.Builder
-	for _, r := range input {
-		b.WriteString(emojiCodeMap[r])
-	}
-	return b.String()
-}
-
-// emojiCodeMap is a mapping from byte to emoji.
-//
-// The mapping is based on draft+2 of https://github.com/emojisum/emojisum.
-// (see: https://github.com/emojisum/emojisum/releases/tag/draft%2B2)
-var emojiCodeMap = []string{
-	"\U0001f44d",                   // 👍 :+1:
-	"\U0001f3b1",                   // 🎱 :8ball:
-	"\u2708\ufe0f",                 // ✈️ :airplane:
-	"\U0001f47d",                   // 👽 :alien:
-	"\u2693",                       // ⚓ :anchor:
-	"\U0001f47c",                   // 👼 :angel:
-	"\U0001f620",                   // 😠 :angry:
-	"\U0001f41c",                   // 🐜 :ant:
-	"\U0001f34e",                   // 🍎 :apple:
-	"\U0001f3a8",                   // 🎨 :art:
-	"\U0001f476",                   // 👶 :baby:
-	"\U0001f37c",                   // 🍼 :baby_bottle:
-	"\U0001f519",                   // 🔙 :back:
-	"\U0001f38d",                   // 🎍 :bamboo:
-	"\U0001f34c",                   // 🍌 :banana:
-	"\U0001f488",                   // 💈 :barber:
-	"\U0001f6c1",                   // 🛁 :bathtub:
-	"\U0001f37a",                   // 🍺 :beer:
-	"\U0001f514",                   // 🔔 :bell:
-	"\U0001f6b4\u200d\u2642\ufe0f", // 🚴‍♂️ :bicyclist:
-	"\U0001f426",                   // 🐦 :bird:
-	"\U0001f382",                   // 🎂 :birthday:
-	"\U0001f33c",                   // 🌼 :blossom:
-	"\U0001f699",                   // 🚙 :blue_car:
-	"\U0001f417",                   // 🐗 :boar:
-	"\U0001f4a3",                   // 💣 :bomb:
-	"\U0001f4a5",                   // 💥 :boom:
-	"\U0001f647\u200d\u2642\ufe0f", // 🙇‍♂️ :bow:
-	"\U0001f466",                   // 👦 :boy:
-	"\U0001f494",                   // 💔 :broken_heart:
-	"\U0001f4a1",                   // 💡 :bulb:
-	"\U0001f68c",                   // 🚌 :bus:
-	"\U0001f335",                   // 🌵 :cactus:
-	"\U0001f4c6",                   // 📆 :calendar:
-	"\U0001f4f7",                   // 📷 :camera:
-	"\U0001f36c",                   // 🍬 :candy:
-	"\U0001f431",                   // 🐱 :cat:
-	"\U0001f352",                   // 🍒 :cherries:
-	"\U0001f6b8",                   // 🚸 :children_crossing:
-	"\U0001f36b",                   // 🍫 :chocolate_bar:
-	"\U0001f44f",                   // 👏 :clap:
-	"\u2601\ufe0f",                 // ☁️ :cloud:
-	"\u2663\ufe0f",                 // ♣️ :clubs:
-	"\U0001f1e8\U0001f1f3",         // 🇨🇳 :cn:
-	"\u2615",                       // ☕ :coffee:
-	"\U0001f6a7",                   // 🚧 :construction:
-	"\U0001f36a",                   // 🍪 :cookie:
-	"\u00a9\ufe0f",                 // ©️ :copyright:
-	"\U0001f33d",                   // 🌽 :corn:
-	"\U0001f42e",                   // 🐮 :cow:
-	"\U0001f319",                   // 🌙 :crescent_moon:
-	"\U0001f451",                   // 👑 :crown:
-	"\U0001f622",                   // 😢 :cry:
-	"\U0001f52e",                   // 🔮 :crystal_ball:
-	"\u27b0",                       // ➰ :curly_loop:
-	"\U0001f46f\u200d\u2640\ufe0f", // 👯‍♀️ :dancers:
-	"\U0001f4a8",                   // 💨 :dash:
-	"\U0001f1e9\U0001f1ea",         // 🇩🇪 :de:
-	"\u2666\ufe0f",                 // ♦️ :diamonds:
-	"\U0001f436",                   // 🐶 :dog:
-	"\U0001f369",                   // 🍩 :doughnut:
-	"\U0001f409",                   // 🐉 :dragon:
-	"\U0001f4c0",                   // 📀 :dvd:
-	"\U0001f442",                   // 👂 :ear:
-	"\U0001f346",                   // 🍆 :eggplant:
-	"\U0001f418",                   // 🐘 :elephant:
-	"\U0001f51a",                   // 🔚 :end:
-	"\u2709",                       // ✉ :envelope:
-	"\U0001f1ea\U0001f1f8",         // 🇪🇸 :es:
-	"\U0001f440",                   // 👀 :eyes:
-	"\U0001f44a",                   // 👊 :facepunch:
-	"\U0001f468\u200d\U0001f469\u200d\U0001f466", // 👨‍👩‍👦 :family:
-	"\U0001f3a1",                         // 🎡 :ferris_wheel:
-	"\U0001f630",                         // 😰 :cold_sweat:
-	"\U0001f525",                         // 🔥 :fire:
-	"\U0001f386",                         // 🎆 :fireworks:
-	"\U0001f4be",                         // 💾 :floppy_disk:
-	"\U0001f3c8",                         // 🏈 :football:
-	"\U0001f374",                         // 🍴 :fork_and_knife:
-	"\U0001f340",                         // 🍀 :four_leaf_clover:
-	"\U0001f1eb\U0001f1f7",               // 🇫🇷 :fr:
-	"\U0001f35f",                         // 🍟 :fries:
-	"\U0001f95c",                         // 🥜 :peanuts:
-	"\U0001f595",                         // 🖕 :fu:
-	"\U0001f315",                         // 🌕 :full_moon:
-	"\U0001f3b2",                         // 🎲 :game_die:
-	"\U0001f1ea\U0001f1fa",               // 🇪🇺 :eu:
-	"\U0001f48e",                         // 💎 :gem:
-	"\U0001f467",                         // 👧 :girl:
-	"\U0001f410",                         // 🐐 :goat:
-	"\U0001f62c",                         // 😬 :grimacing:
-	"\U0001f601",                         // 😁 :grin:
-	"\U0001f482\u200d\u2642\ufe0f",       // 💂‍♂️ :guardsman:
-	"\U0001f3b8",                         // 🎸 :guitar:
-	"\U0001f52b",                         // 🔫 :gun:
-	"\U0001f354",                         // 🍔 :hamburger:
-	"\U0001f528",                         // 🔨 :hammer:
-	"\U0001f439",                         // 🐹 :hamster:
-	"\U0001f649",                         // 🙉 :hear_no_evil:
-	"\u2764\ufe0f",                       // ❤️ :heart:
-	"\U0001f63b",                         // 😻 :heart_eyes_cat:
-	"\u2763\ufe0f",                       // ❣️ :heavy_heart_exclamation:
-	"\u2714\ufe0f",                       // ✔️ :heavy_check_mark:
-	"\U0001f5ff",                         // 🗿 :moyai:
-	"\U0001f3ee",                         // 🏮 :izakaya_lantern:
-	"\U0001f681",                         // 🚁 :helicopter:
-	"\U0001f52a",                         // 🔪 :hocho:
-	"\U0001f41d",                         // 🐝 :honeybee:
-	"\U0001f434",                         // 🐴 :horse:
-	"\U0001f3c7",                         // 🏇 :horse_racing:
-	"\u231b",                             // ⌛ :hourglass:
-	"\U0001f3e0",                         // 🏠 :house:
-	"\U0001f575\ufe0f\u200d\u2640\ufe0f", // 🕵️‍♀️ :female_detective:
-	"\U0001f366",                         // 🍦 :icecream:
-	"\U0001f47f",                         // 👿 :imp:
-	"\U0001f1ee\U0001f1f9",               // 🇮🇹 :it:
-	"\U0001f383",                         // 🎃 :jack_o_lantern:
-	"\U0001f47a",                         // 👺 :japanese_goblin:
-	"\U0001f1ef\U0001f1f5",               // 🇯🇵 :jp:
-	"\U0001f511",                         // 🔑 :key:
-	"\U0001f48b",                         // 💋 :kiss:
-	"\U0001f63d",                         // 😽 :kissing_cat:
-	"\U0001f428",                         // 🐨 :koala:
-	"\U0001f1f0\U0001f1f7",               // 🇰🇷 :kr:
-	"\U0001f34b",                         // 🍋 :lemon:
-	"\U0001f484",                         // 💄 :lipstick:
-	"\U0001f512",                         // 🔒 :lock:
-	"\U0001f36d",                         // 🍭 :lollipop:
-	"\U0001f468",                         // 👨 :man:
-	"\U0001f341",                         // 🍁 :maple_leaf:
-	"\U0001f637",                         // 😷 :mask:
-	"\U0001f918",                         // 🤘 :metal:
-	"\U0001f52c",                         // 🔬 :microscope:
-	"\U0001f4b0",                         // 💰 :moneybag:
-	"\U0001f412",                         // 🐒 :monkey:
-	"\U0001f5fb",                         // 🗻 :mount_fuji:
-	"\U0001f4aa",                         // 💪 :muscle:
-	"\U0001f344",                         // 🍄 :mushroom:
-	"\U0001f3b9",                         // 🎹 :musical_keyboard:
-	"\U0001f3bc",                         // 🎼 :musical_score:
-	"\U0001f485",                         // 💅 :nail_care:
-	"\U0001f311",                         // 🌑 :new_moon:
-	"\u26d4",                             // ⛔ :no_entry:
-	"\U0001f443",                         // 👃 :nose:
-	"\U0001f39b\ufe0f",                   // 🎛️ :control_knobs:
-	"\U0001f529",                         // 🔩 :nut_and_bolt:
-	"\u2b55",                             // ⭕ :o:
-	"\U0001f30a",                         // 🌊 :ocean:
-	"\U0001f44c",                         // 👌 :ok_hand:
-	"\U0001f51b",                         // 🔛 :on:
-	"\U0001f4e6",                         // 📦 :package:
-	"\U0001f334",                         // 🌴 :palm_tree:
-	"\U0001f43c",                         // 🐼 :panda_face:
-	"\U0001f4ce",                         // 📎 :paperclip:
-	"\u26c5",                             // ⛅ :partly_sunny:
-	"\U0001f6c2",                         // 🛂 :passport_control:
-	"\U0001f43e",                         // 🐾 :paw_prints:
-	"\U0001f351",                         // 🍑 :peach:
-	"\U0001f427",                         // 🐧 :penguin:
-	"\u260e\ufe0f",                       // ☎️ :phone:
-	"\U0001f437",                         // 🐷 :pig:
-	"\U0001f48a",                         // 💊 :pill:
-	"\U0001f34d",                         // 🍍 :pineapple:
-	"\U0001f355",                         // 🍕 :pizza:
-	"\U0001f448",                         // 👈 :point_left:
-	"\U0001f449",                         // 👉 :point_right:
-	"\U0001f4a9",                         // 💩 :poop:
-	"\U0001f357",                         // 🍗 :poultry_leg:
-	"\U0001f64f",                         // 🙏 :pray:
-	"\U0001f478",                         // 👸 :princess:
-	"\U0001f45b",                         // 👛 :purse:
-	"\U0001f4cc",                         // 📌 :pushpin:
-	"\U0001f430",                         // 🐰 :rabbit:
-	"\U0001f308",                         // 🌈 :rainbow:
-	"\u270b",                             // ✋ :raised_hand:
-	"\u267b\ufe0f",                       // ♻️ :recycle:
-	"\U0001f697",                         // 🚗 :red_car:
-	"\u00ae\ufe0f",                       // ®️ :registered:
-	"\U0001f380",                         // 🎀 :ribbon:
-	"\U0001f35a",                         // 🍚 :rice:
-	"\U0001f680",                         // 🚀 :rocket:
-	"\U0001f3a2",                         // 🎢 :roller_coaster:
-	"\U0001f413",                         // 🐓 :rooster:
-	"\U0001f1f7\U0001f1fa",               // 🇷🇺 :ru:
-	"\u26f5",                             // ⛵ :sailboat:
-	"\U0001f385",                         // 🎅 :santa:
-	"\U0001f6f0\ufe0f",                   // 🛰️ :satellite:
-	"\U0001f606",                         // 😆 :satisfied:
-	"\U0001f3b7",                         // 🎷 :saxophone:
-	"\u2702\ufe0f",                       // ✂️ :scissors:
-	"\U0001f648",                         // 🙈 :see_no_evil:
-	"\U0001f411",                         // 🐑 :sheep:
-	"\U0001f41a",                         // 🐚 :shell:
-	"\U0001f45e",                         // 👞 :shoe:
-	"\U0001f3bf",                         // 🎿 :ski:
-	"\U0001f480",                         // 💀 :skull:
-	"\U0001f62a",                         // 😪 :sleepy:
-	"\U0001f604",                         // 😄 :smile:
-	"\U0001f63a",                         // 😺 :smiley_cat:
-	"\U0001f60f",                         // 😏 :smirk:
-	"\U0001f6ac",                         // 🚬 :smoking:
-	"\U0001f40c",                         // 🐌 :snail:
-	"\U0001f40d",                         // 🐍 :snake:
-	"\u2744\ufe0f",                       // ❄️ :snowflake:
-	"\u26bd",                             // ⚽ :soccer:
-	"\U0001f51c",                         // 🔜 :soon:
-	"\U0001f47e",                         // 👾 :space_invader:
-	"\u2660\ufe0f",                       // ♠️ :spades:
-	"\U0001f64a",                         // 🙊 :speak_no_evil:
-	"\u2b50",                             // ⭐ :star:
-	"\u26f2",                             // ⛲ :fountain:
-	"\U0001f5fd",                         // 🗽 :statue_of_liberty:
-	"\U0001f682",                         // 🚂 :steam_locomotive:
-	"\U0001f33b",                         // 🌻 :sunflower:
-	"\U0001f60e",                         // 😎 :sunglasses:
-	"\u2600\ufe0f",                       // ☀️ :sunny:
-	"\U0001f305",                         // 🌅 :sunrise:
-	"\U0001f3c4\u200d\u2642\ufe0f",       // 🏄‍♂️ :surfer:
-	"\U0001f3ca\u200d\u2642\ufe0f",       // 🏊‍♂️ :swimmer:
-	"\U0001f489",                         // 💉 :syringe:
-	"\U0001f389",                         // 🎉 :tada:
-	"\U0001f34a",                         // 🍊 :tangerine:
-	"\U0001f695",                         // 🚕 :taxi:
-	"\U0001f3be",                         // 🎾 :tennis:
-	"\u26fa",                             // ⛺ :tent:
-	"\U0001f4ad",                         // 💭 :thought_balloon:
-	"\u2122\ufe0f",                       // ™️ :tm:
-	"\U0001f6bd",                         // 🚽 :toilet:
-	"\U0001f445",                         // 👅 :tongue:
-	"\U0001f3a9",                         // 🎩 :tophat:
-	"\U0001f69c",                         // 🚜 :tractor:
-	"\U0001f68e",                         // 🚎 :trolleybus:
-	"\U0001f922",                         // 🤢 :nauseated_face:
-	"\U0001f3c6",                         // 🏆 :trophy:
-	"\U0001f3ba",                         // 🎺 :trumpet:
-	"\U0001f422",                         // 🐢 :turtle:
-	"\U0001f3a0",                         // 🎠 :carousel_horse:
-	"\U0001f46d",                         // 👭 :two_women_holding_hands:
-	"\U0001f1ec\U0001f1e7",               // 🇬🇧 :uk:
-	"\u2602\ufe0f",                       // ☂️ :umbrella:
-	"\U0001f513",                         // 🔓 :unlock:
-	"\U0001f1fa\U0001f1f8",               // 🇺🇸 :us:
-	"\u270c\ufe0f",                       // ✌️ :v:
-	"\U0001f4fc",                         // 📼 :vhs:
-	"\U0001f3bb",                         // 🎻 :violin:
-	"\u26a0\ufe0f",                       // ⚠️ :warning:
-	"\U0001f349",                         // 🍉 :watermelon:
-	"\U0001f44b",                         // 👋 :wave:
-	"\u3030\ufe0f",                       // 〰️ :wavy_dash:
-	"\U0001f6be",                         // 🚾 :wc:
-	"\u267f",                             // ♿ :wheelchair:
-	"\U0001f469",                         // 👩 :woman:
-	"\u274c",                             // ❌ :x:
-	"\U0001f60b",                         // 😋 :yum:
-	"\u26a1",                             // ⚡ :zap:
-	"\U0001f4a4",                         // 💤 :zzz:
-}
diff --git a/sshutil/fingerprint.go b/sshutil/fingerprint.go
deleted file mode 100644
index 0017584..0000000
--- a/sshutil/fingerprint.go
+++ /dev/null
@@ -1,140 +0,0 @@
-package sshutil
-
-import (
-	"crypto/dsa" //nolint:staticcheck // support for DSA fingerprints
-	"crypto/rsa"
-	"crypto/sha256"
-	"fmt"
-
-	"github.com/pkg/errors"
-	"go.step.sm/crypto/fingerprint"
-	"golang.org/x/crypto/ssh"
-)
-
-// FingerprintEncoding defines the supported encodings for SSH key and
-// certificate fingerprints.
-type FingerprintEncoding = fingerprint.Encoding
-
-// Supported fingerprint encodings.
-const (
-	// DefaultFingerprint represents base64RawStd encoding of the fingerprint.
-	DefaultFingerprint = FingerprintEncoding(0)
-	// HexFingerprint represents the hex encoding of the fingerprint.
-	HexFingerprint = fingerprint.HexFingerprint
-	// Base64Fingerprint represents the base64 encoding of the fingerprint.
-	Base64Fingerprint = fingerprint.Base64Fingerprint
-	// Base64URLFingerprint represents the base64URL encoding of the fingerprint.
-	Base64URLFingerprint = fingerprint.Base64URLFingerprint
-	// Base64RawFingerprint represents the base64RawStd encoding of the fingerprint.
-	Base64RawFingerprint = fingerprint.Base64RawFingerprint
-	// Base64RawURLFingerprint represents the base64RawURL encoding of the fingerprint.
-	Base64RawURLFingerprint = fingerprint.Base64RawURLFingerprint
-	// EmojiFingerprint represents the emoji encoding of the fingerprint.
-	EmojiFingerprint = fingerprint.EmojiFingerprint
-)
-
-// Fingerprint returns the SHA-256 fingerprint of an ssh public key or
-// certificate.
-func Fingerprint(pub ssh.PublicKey) string {
-	return EncodedFingerprint(pub, DefaultFingerprint)
-}
-
-// EncodedFingerprint returns the SHA-256 hash of an ssh public key or
-// certificate using the specified encoding. If an invalid encoding is passed,
-// the return value will be an empty string.
-func EncodedFingerprint(pub ssh.PublicKey, encoding FingerprintEncoding) string {
-	var fp string
-
-	sum := sha256.Sum256(pub.Marshal())
-	switch encoding {
-	case DefaultFingerprint:
-		fp = fingerprint.Fingerprint(sum[:], Base64RawFingerprint)
-	default:
-		fp = fingerprint.Fingerprint(sum[:], encoding)
-	}
-	if fp == "" {
-		return ""
-	}
-	return "SHA256:" + fp
-}
-
-// FormatFingerprint parses a public key from an authorized_keys file used in
-// OpenSSH and returns a public key fingerprint in the following format:
-//
-//	<size> SHA256:<base64-raw-fingerprint> <comment> (<type)
-func FormatFingerprint(in []byte, encoding FingerprintEncoding) (string, error) {
-	key, comment, _, _, err := ssh.ParseAuthorizedKey(in)
-	if err != nil {
-		return "", fmt.Errorf("error parsing public key: %w", err)
-	}
-	if comment == "" {
-		comment = "no comment"
-	}
-
-	typ, size, err := publicKeyTypeAndSize(key)
-	if err != nil {
-		return "", fmt.Errorf("error determining key type and size: %w", err)
-	}
-
-	fp := EncodedFingerprint(key, encoding)
-	if fp == "" {
-		return "", fmt.Errorf("unsupported encoding format %v", encoding)
-	}
-
-	return fmt.Sprintf("%d %s %s (%s)", size, fp, comment, typ), nil
-}
-
-func publicKeyTypeAndSize(key ssh.PublicKey) (string, int, error) {
-	var isCert bool
-	if cert, ok := key.(*ssh.Certificate); ok {
-		key = cert.Key
-		isCert = true
-	}
-
-	var typ string
-	var size int
-	switch key.Type() {
-	case ssh.KeyAlgoECDSA256:
-		typ, size = "ECDSA", 256
-	case ssh.KeyAlgoECDSA384:
-		typ, size = "ECDSA", 384
-	case ssh.KeyAlgoECDSA521:
-		typ, size = "ECDSA", 521
-	case ssh.KeyAlgoSKECDSA256:
-		typ, size = "SK-ECDSA", 256
-	case ssh.KeyAlgoED25519:
-		typ, size = "ED25519", 256
-	case ssh.KeyAlgoSKED25519:
-		typ, size = "SK-ED25519", 256
-	case ssh.KeyAlgoRSA:
-		typ = "RSA"
-		cpk, err := CryptoPublicKey(key)
-		if err != nil {
-			return "", 0, err
-		}
-		k, ok := cpk.(*rsa.PublicKey)
-		if !ok {
-			return "", 0, errors.New("unsupported key: not an RSA public key")
-		}
-		size = 8 * k.Size()
-	case ssh.KeyAlgoDSA:
-		typ = "DSA"
-		cpk, err := CryptoPublicKey(key)
-		if err != nil {
-			return "", 0, err
-		}
-		k, ok := cpk.(*dsa.PublicKey)
-		if !ok {
-			return "", 0, errors.New("unsupported key: not a DSA public key")
-		}
-		size = k.Parameters.P.BitLen()
-	default:
-		return "", 0, errors.Errorf("public key %s is not supported", key.Type())
-	}
-
-	if isCert {
-		typ += "-CERT"
-	}
-
-	return typ, size, nil
-}
diff --git a/sshutil/sshutil.go b/sshutil/sshutil.go
index c309c2d..870ded3 100644
--- a/sshutil/sshutil.go
+++ b/sshutil/sshutil.go
@@ -2,7 +2,6 @@ package sshutil
 
 import (
 	"crypto"
-	"crypto/dsa" //nolint:staticcheck // support for DSA fingerprints
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/elliptic"
@@ -17,7 +16,7 @@ import (
 // *agent.Key.
 func CryptoPublicKey(pub interface{}) (crypto.PublicKey, error) {
 	switch p := pub.(type) {
-	case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey, *dsa.PublicKey:
+	case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
 		return pub, nil
 	case ssh.CryptoPublicKey:
 		return p.CryptoPublicKey(), nil
diff --git a/x509util/certificate.go b/x509util/certificate.go
index e4938b1..a3c1956 100644
--- a/x509util/certificate.go
+++ b/x509util/certificate.go
@@ -55,7 +55,7 @@ func NewCertificate(cr *x509.CertificateRequest, opts ...Option) (*Certificate,
 	// If no template use only the certificate request with the default leaf key
 	// usages.
 	if o.CertBuffer == nil {
-		return NewCertificateRequestFromX509(cr).GetLeafCertificate(), nil
+		return newCertificateRequest(cr).GetLeafCertificate(), nil
 	}
 
 	// With templates
diff --git a/x509util/certificate_request.go b/x509util/certificate_request.go
index 161ff3e..3f0b955 100644
--- a/x509util/certificate_request.go
+++ b/x509util/certificate_request.go
@@ -60,15 +60,15 @@ func NewCertificateRequest(signer crypto.Signer, opts ...Option) (*CertificateRe
 	return &cr, nil
 }
 
-// NewCertificateRequestFromX509 creates a CertificateRequest from an
-// x509.CertificateRequest.
+// newCertificateRequest is an internal method that creates a CertificateRequest
+// from an x509.CertificateRequest.
 //
 // This method is used to create the template variable .Insecure.CR or to
-// initialize the Certificate when no templates are used.
-// NewCertificateRequestFromX509 will always ignore the SignatureAlgorithm
-// because we cannot guarantee that the signer will be able to sign a
-// certificate template if Certificate.SignatureAlgorithm is set.
-func NewCertificateRequestFromX509(cr *x509.CertificateRequest) *CertificateRequest {
+// initialize the Certificate when no templates are used. newCertificateRequest
+// will always ignore the SignatureAlgorithm because we cannot guarantee that
+// the signer will be able to sign a certificate template if
+// Certificate.SignatureAlgorithm is set.
+func newCertificateRequest(cr *x509.CertificateRequest) *CertificateRequest {
 	// Set SubjectAltName extension as critical if Subject is empty.
 	fixSubjectAltName(cr)
 	return &CertificateRequest{
diff --git a/x509util/extensions.go b/x509util/extensions.go
index 3bbdd4b..11f8e7f 100644
--- a/x509util/extensions.go
+++ b/x509util/extensions.go
@@ -545,46 +545,6 @@ func (k *KeyUsage) UnmarshalJSON(data []byte) error {
 	return nil
 }
 
-// MarshalJSON implements the json.Marshaler interface and converts a key usage
-// into a list of strings.
-func (k KeyUsage) MarshalJSON() ([]byte, error) {
-	var usages []string
-
-	if x509.KeyUsage(k)&x509.KeyUsageDigitalSignature != 0 {
-		usages = append(usages, KeyUsageDigitalSignature)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageContentCommitment != 0 {
-		usages = append(usages, KeyUsageContentCommitment)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageKeyEncipherment != 0 {
-		usages = append(usages, KeyUsageKeyEncipherment)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageDataEncipherment != 0 {
-		usages = append(usages, KeyUsageDataEncipherment)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageKeyAgreement != 0 {
-		usages = append(usages, KeyUsageKeyAgreement)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageCertSign != 0 {
-		usages = append(usages, KeyUsageCertSign)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageCRLSign != 0 {
-		usages = append(usages, KeyUsageCRLSign)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageEncipherOnly != 0 {
-		usages = append(usages, KeyUsageEncipherOnly)
-	}
-	if x509.KeyUsage(k)&x509.KeyUsageDecipherOnly != 0 {
-		usages = append(usages, KeyUsageDecipherOnly)
-	}
-
-	if len(usages) == 0 && k != 0 {
-		return nil, fmt.Errorf("cannot marshal key usage %v", k)
-	}
-
-	return json.Marshal(usages)
-}
-
 // ExtKeyUsage represents a JSON array of extended key usages.
 type ExtKeyUsage []x509.ExtKeyUsage
 
@@ -643,49 +603,6 @@ func (k *ExtKeyUsage) UnmarshalJSON(data []byte) error {
 	return nil
 }
 
-// MarshalJSON implements the json.Marshaler interface and converts a list of
-// extended key usages to a list of strings
-func (k ExtKeyUsage) MarshalJSON() ([]byte, error) {
-	usages := make([]string, len(k))
-
-	for i, eku := range k {
-		switch eku {
-		case x509.ExtKeyUsageAny:
-			usages[i] = ExtKeyUsageAny
-		case x509.ExtKeyUsageServerAuth:
-			usages[i] = ExtKeyUsageServerAuth
-		case x509.ExtKeyUsageClientAuth:
-			usages[i] = ExtKeyUsageClientAuth
-		case x509.ExtKeyUsageCodeSigning:
-			usages[i] = ExtKeyUsageCodeSigning
-		case x509.ExtKeyUsageEmailProtection:
-			usages[i] = ExtKeyUsageEmailProtection
-		case x509.ExtKeyUsageIPSECEndSystem:
-			usages[i] = ExtKeyUsageIPSECEndSystem
-		case x509.ExtKeyUsageIPSECTunnel:
-			usages[i] = ExtKeyUsageIPSECTunnel
-		case x509.ExtKeyUsageIPSECUser:
-			usages[i] = ExtKeyUsageIPSECUser
-		case x509.ExtKeyUsageTimeStamping:
-			usages[i] = ExtKeyUsageTimeStamping
-		case x509.ExtKeyUsageOCSPSigning:
-			usages[i] = ExtKeyUsageOCSPSigning
-		case x509.ExtKeyUsageMicrosoftServerGatedCrypto:
-			usages[i] = ExtKeyUsageMicrosoftServerGatedCrypto
-		case x509.ExtKeyUsageNetscapeServerGatedCrypto:
-			usages[i] = ExtKeyUsageNetscapeServerGatedCrypto
-		case x509.ExtKeyUsageMicrosoftCommercialCodeSigning:
-			usages[i] = ExtKeyUsageMicrosoftCommercialCodeSigning
-		case x509.ExtKeyUsageMicrosoftKernelCodeSigning:
-			usages[i] = ExtKeyUsageMicrosoftKernelCodeSigning
-		default:
-			return nil, fmt.Errorf("unsupported extKeyUsage %v", eku)
-		}
-	}
-
-	return json.Marshal(usages)
-}
-
 // UnknownExtKeyUsage represents the list of OIDs of extended key usages unknown
 // to crypto/x509.
 type UnknownExtKeyUsage MultiObjectIdentifier
diff --git a/x509util/fingerprint.go b/x509util/fingerprint.go
deleted file mode 100644
index e75a6df..0000000
--- a/x509util/fingerprint.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package x509util
-
-import (
-	"crypto/sha256"
-	"crypto/x509"
-
-	"go.step.sm/crypto/fingerprint"
-)
-
-// FingerprintEncoding defines the supported encodings in certificate
-// fingerprints.
-type FingerprintEncoding = fingerprint.Encoding
-
-// Supported fingerprint encodings.
-const (
-	// DefaultFingerprint represents the hex encoding of the fingerprint.
-	DefaultFingerprint = FingerprintEncoding(0)
-	// HexFingerprint represents the hex encoding of the fingerprint.
-	HexFingerprint = fingerprint.HexFingerprint
-	// Base64Fingerprint represents the base64 encoding of the fingerprint.
-	Base64Fingerprint = fingerprint.Base64Fingerprint
-	// Base64URLFingerprint represents the base64URL encoding of the fingerprint.
-	Base64URLFingerprint = fingerprint.Base64URLFingerprint
-	// Base64RawFingerprint represents the base64RawStd encoding of the fingerprint.
-	Base64RawFingerprint = fingerprint.Base64RawFingerprint
-	// Base64RawURLFingerprint represents the base64RawURL encoding of the fingerprint.
-	Base64RawURLFingerprint = fingerprint.Base64RawURLFingerprint
-	// EmojiFingerprint represents the emoji encoding of the fingerprint.
-	EmojiFingerprint = fingerprint.EmojiFingerprint
-)
-
-// Fingerprint returns the SHA-256 fingerprint of the certificate.
-func Fingerprint(cert *x509.Certificate) string {
-	return EncodedFingerprint(cert, DefaultFingerprint)
-}
-
-// EncodedFingerprint returns the SHA-256 hash of the certificate using the
-// specified encoding. If an invalid encoding is passed, the return value will
-// be an empty string.
-func EncodedFingerprint(cert *x509.Certificate, encoding FingerprintEncoding) string {
-	sum := sha256.Sum256(cert.Raw)
-	switch encoding {
-	case DefaultFingerprint:
-		return fingerprint.Fingerprint(sum[:], HexFingerprint)
-	default:
-		return fingerprint.Fingerprint(sum[:], encoding)
-	}
-}
diff --git a/x509util/templates.go b/x509util/templates.go
index 3199d22..059cf7f 100644
--- a/x509util/templates.go
+++ b/x509util/templates.go
@@ -123,7 +123,7 @@ func (t TemplateData) SetAuthorizationCertificateChain(chain interface{}) {
 // SetCertificateRequest sets the given certificate request in the insecure
 // template data.
 func (t TemplateData) SetCertificateRequest(cr *x509.CertificateRequest) {
-	t.SetInsecure(CertificateRequestKey, NewCertificateRequestFromX509(cr))
+	t.SetInsecure(CertificateRequestKey, newCertificateRequest(cr))
 }
 
 // SetWebhook sets the given webhook response in the webhooks template data.
diff --git a/x509util/utils.go b/x509util/utils.go
index b3961da..ddb09e5 100644
--- a/x509util/utils.go
+++ b/x509util/utils.go
@@ -5,9 +5,12 @@ import (
 	"crypto"
 	"crypto/rand"
 	"crypto/sha1" //nolint:gosec // SubjectKeyIdentifier by RFC 5280
+	"crypto/sha256"
 	"crypto/x509"
 	"crypto/x509/pkix"
 	"encoding/asn1"
+	"encoding/base64"
+	"encoding/hex"
 	"math/big"
 	"net"
 	"net/url"
@@ -19,6 +22,17 @@ import (
 	"golang.org/x/net/idna"
 )
 
+// FingerprintEncoding defines the supported encodigns in certificate
+// fingerprints.
+type FingerprintEncoding int
+
+// Supported fingerprint encodings.
+const (
+	HexFingerprint FingerprintEncoding = iota
+	Base64Fingerprint
+	Base64UrlFingerprint
+)
+
 var emptyASN1Subject = []byte{0x30, 0}
 
 // SanitizeName converts the given domain to its ASCII form.
@@ -88,6 +102,28 @@ func CreateSANs(sans []string) []SubjectAlternativeName {
 	return sanTypes
 }
 
+// Fingerprint returns the SHA-256 fingerprint of the certificate.
+func Fingerprint(cert *x509.Certificate) string {
+	return EncodedFingerprint(cert, HexFingerprint)
+}
+
+// EncodedFingerprint returns an encoded the SHA-256 fingerprint of the
+// certificate using the specified encoding. In an invalid encoding is passed,
+// the return value will be an empty string.
+func EncodedFingerprint(cert *x509.Certificate, encoding FingerprintEncoding) string {
+	sum := sha256.Sum256(cert.Raw)
+	switch encoding {
+	case HexFingerprint:
+		return strings.ToLower(hex.EncodeToString(sum[:]))
+	case Base64Fingerprint:
+		return base64.StdEncoding.EncodeToString(sum[:])
+	case Base64UrlFingerprint:
+		return base64.URLEncoding.EncodeToString(sum[:])
+	default:
+		return ""
+	}
+}
+
 // generateSerialNumber returns a random serial number.
 func generateSerialNumber() (*big.Int, error) {
 	limit := new(big.Int).Lsh(big.NewInt(1), 128)


Test patch:
diff --git a/fingerprint/fingerprint_test.go b/fingerprint/fingerprint_test.go
deleted file mode 100644
index ac09c45..0000000
--- a/fingerprint/fingerprint_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package fingerprint
-
-import (
-	"crypto"
-	"errors"
-	"hash"
-	"testing"
-)
-
-type failHash struct{}
-
-func (h failHash) Write(b []byte) (int, error) {
-	return 0, errors.New("failed to write")
-}
-func (h failHash) Sum(b []byte) []byte { return nil }
-func (h failHash) Reset()              {}
-func (h failHash) Size() int           { return 32 }
-func (h failHash) BlockSize() int      { return 32 }
-
-func TestNew(t *testing.T) {
-	data := []byte(`Lorem ipsum dolor sit amet`)
-	// This overwrites MD4 with failHash
-	crypto.RegisterHash(1, func() hash.Hash {
-		return failHash{}
-	})
-	type args struct {
-		data     []byte
-		h        crypto.Hash
-		encoding Encoding
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    string
-		wantErr bool
-	}{
-		{"sha256", args{data, crypto.SHA256, HexFingerprint}, "16aba5393ad72c0041f5600ad3c2c52ec437a2f0c7fc08fadfc3c0fe9641d7a3", false},
-		{"unavailable", args{data, crypto.Hash(1000), HexFingerprint}, "", true},
-		{"fail encoding", args{data, crypto.SHA256, Encoding(1000)}, "", true},
-		{"fail write", args{data, crypto.Hash(1), HexFingerprint}, "", true},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := New(tt.args.data, tt.args.h, tt.args.encoding)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("New() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestFingerprint(t *testing.T) {
-	digest := []byte{
-		0x38, 0x01, 0x16, 0x21, 0xec, 0xdc, 0xc2, 0x17,
-		0x2e, 0x93, 0x3a, 0x1e, 0xf2, 0x31, 0x7e, 0xfc,
-		0x53, 0x5a, 0x16, 0x1c, 0x00, 0x33, 0x3a, 0xee,
-		0x3f, 0x84, 0xab, 0xfa, 0xb4, 0xe6, 0x40, 0xbf,
-	}
-	type args struct {
-		digest   []byte
-		encoding Encoding
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		{"HexFingerprint", args{digest, HexFingerprint}, "38011621ecdcc2172e933a1ef2317efc535a161c00333aee3f84abfab4e640bf"},
-		{"Base64Fingerprint", args{digest, Base64Fingerprint}, "OAEWIezcwhcukzoe8jF+/FNaFhwAMzruP4Sr+rTmQL8="},
-		{"Base64URLFingerprint", args{digest, Base64URLFingerprint}, "OAEWIezcwhcukzoe8jF-_FNaFhwAMzruP4Sr-rTmQL8="},
-		{"Base64RawFingerprint", args{digest, Base64RawFingerprint}, "OAEWIezcwhcukzoe8jF+/FNaFhwAMzruP4Sr+rTmQL8"},
-		{"Base64RawURLFingerprint", args{digest, Base64RawURLFingerprint}, "OAEWIezcwhcukzoe8jF-_FNaFhwAMzruP4Sr-rTmQL8"},
-		{"EmojiFingerprint", args{digest, EmojiFingerprint}, "💨🎱🌼📆🎠🎉🎿🚙🍪🌊♦️💡✌️🐮🔒❌🖕😬🌼👦👍👑♦️🇬🇧👂🔬📌♿🚀🚜🍆🐑"},
-		{"Unknown", args{digest, 0}, ""},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := Fingerprint(tt.args.digest, tt.args.encoding); got != tt.want {
-				t.Errorf("Fingerprint() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/internal/emoji/emoji_test.go b/internal/emoji/emoji_test.go
deleted file mode 100644
index e9cba99..0000000
--- a/internal/emoji/emoji_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package emoji
-
-import "testing"
-
-func TestEmoji(t *testing.T) {
-	type args struct {
-		input []byte
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		{"ok", args{[]byte{0x00, 0x10, 0x50, 0xAA, 0xFF}}, "👍🛁🇫🇷👛💤"},
-		{"empty", args{[]byte{}}, ""},
-		{"nil", args{nil}, ""},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := Emoji(tt.args.input); got != tt.want {
-				t.Errorf("Emoji() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/sshutil/fingerprint_test.go b/sshutil/fingerprint_test.go
deleted file mode 100644
index f10394b..0000000
--- a/sshutil/fingerprint_test.go
+++ /dev/null
@@ -1,246 +0,0 @@
-package sshutil
-
-import (
-	"bytes"
-	"crypto"
-	"crypto/dsa" //nolint:staticcheck // support for DSA fingerprints
-	"crypto/rand"
-	"encoding/base64"
-	"encoding/hex"
-	"testing"
-
-	"go.step.sm/crypto/internal/emoji"
-	"golang.org/x/crypto/ssh"
-)
-
-func generateCertificate(t *testing.T) ssh.PublicKey {
-	t.Helper()
-	key, signer := mustGenerateKey(t)
-
-	cert, err := CreateCertificate(&ssh.Certificate{
-		Nonce:           []byte("0123456789"),
-		Key:             key,
-		Serial:          123,
-		CertType:        ssh.HostCert,
-		KeyId:           "foo",
-		ValidPrincipals: []string{"foo.internal"},
-		ValidAfter:      1111,
-		ValidBefore:     2222,
-		Permissions:     ssh.Permissions{},
-		Reserved:        []byte("reserved"),
-	}, signer)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return cert
-}
-
-func TestFingerprint(t *testing.T) {
-	ecKey, sshECKey := generateKey(t, "EC", "P-256", 0)
-	edKey, sshEDKey := generateKey(t, "OKP", "Ed25519", 0)
-	_, sshRSAKey := generateKey(t, "RSA", "", 2048)
-
-	skECKey := generateFakeSKKey(t, ecKey)
-	skEDKey := generateFakeSKKey(t, edKey)
-	sshCert := generateCertificate(t)
-
-	type args struct {
-		pub ssh.PublicKey
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		{"ok ECDSA", args{sshECKey}, ssh.FingerprintSHA256(sshECKey)},
-		{"ok ED25519", args{sshEDKey}, ssh.FingerprintSHA256(sshEDKey)},
-		{"ok RSA", args{sshRSAKey}, ssh.FingerprintSHA256(sshRSAKey)},
-		{"ok SK-ECDSA", args{skECKey}, ssh.FingerprintSHA256(skECKey)},
-		{"ok SK-ED25519", args{skEDKey}, ssh.FingerprintSHA256(skEDKey)},
-		{"ok CERT", args{sshCert}, ssh.FingerprintSHA256(sshCert)},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := Fingerprint(tt.args.pub); got != tt.want {
-				t.Errorf("Fingerprint() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestEncodedFingerprint(t *testing.T) {
-	_, sshECKey := generateKey(t, "EC", "P-256", 0)
-
-	expected := ssh.FingerprintSHA256(sshECKey)
-	b, err := base64.RawStdEncoding.DecodeString(expected[7:])
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	type args struct {
-		pub      ssh.PublicKey
-		encoding FingerprintEncoding
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		{"default", args{sshECKey, 0}, ssh.FingerprintSHA256(sshECKey)},
-		{"Base64RawFingerprint", args{sshECKey, Base64RawFingerprint}, expected},
-		{"Base64RawURLFingerprint", args{sshECKey, Base64RawURLFingerprint}, "SHA256:" + base64.RawURLEncoding.EncodeToString(b)},
-		{"Base64Fingerprint", args{sshECKey, Base64Fingerprint}, "SHA256:" + base64.StdEncoding.EncodeToString(b)},
-		{"Base64URLFingerprint", args{sshECKey, Base64URLFingerprint}, "SHA256:" + base64.URLEncoding.EncodeToString(b)},
-		{"HexFingerprint", args{sshECKey, HexFingerprint}, "SHA256:" + hex.EncodeToString(b)},
-		{"EmojiFingerprint", args{sshECKey, EmojiFingerprint}, "SHA256:" + emoji.Emoji(b)},
-		{"fail", args{sshECKey, 100}, ""},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := EncodedFingerprint(tt.args.pub, tt.args.encoding); got != tt.want {
-				t.Errorf("EncodedFingerprint() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestFormatFingerprint(t *testing.T) {
-	ecKey, sshECKey := generateKey(t, "EC", "P-256", 0)
-	_, sshEC384Key := generateKey(t, "EC", "P-384", 0)
-	_, sshEC521Key := generateKey(t, "EC", "P-521", 0)
-	edKey, sshEDKey := generateKey(t, "OKP", "Ed25519", 0)
-	_, sshRSAKey := generateKey(t, "RSA", "", 2048)
-
-	skECKey := generateFakeSKKey(t, ecKey)
-	skEDKey := generateFakeSKKey(t, edKey)
-	sshCert := generateCertificate(t)
-
-	dsaKey := new(dsa.PrivateKey)
-	if err := dsa.GenerateParameters(&dsaKey.Parameters, rand.Reader, dsa.L1024N160); err != nil {
-		t.Fatal(err)
-	}
-	if err := dsa.GenerateKey(dsaKey, rand.Reader); err != nil {
-		t.Fatal(err)
-	}
-	dsaSigner, err := ssh.NewSignerFromKey(dsaKey)
-	if err != nil {
-		t.Fatal(err)
-	}
-	sshDSAKey := dsaSigner.PublicKey()
-
-	ec256Bytes, err := base64.RawStdEncoding.DecodeString(ssh.FingerprintSHA256(sshECKey)[7:])
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	marshal := func(pub ssh.PublicKey, comment string) []byte {
-		b := &bytes.Buffer{}
-		b.WriteString(pub.Type())
-		b.WriteByte(' ')
-		e := base64.NewEncoder(base64.StdEncoding, b)
-		_, _ = e.Write(pub.Marshal())
-		e.Close()
-		if comment != "" {
-			b.WriteString(" " + comment)
-		}
-		b.WriteByte('\n')
-		return b.Bytes()
-	}
-
-	type args struct {
-		in       []byte
-		encoding FingerprintEncoding
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    string
-		wantErr bool
-	}{
-		{"P256", args{marshal(sshECKey, "jane@example.com"), 0}, "256 " + ssh.FingerprintSHA256(sshECKey) + " jane@example.com (ECDSA)", false},
-		{"P384", args{marshal(sshEC384Key, "jane@example.com"), 0}, "384 " + ssh.FingerprintSHA256(sshEC384Key) + " jane@example.com (ECDSA)", false},
-		{"P521", args{marshal(sshEC521Key, "jane@example.com"), 0}, "521 " + ssh.FingerprintSHA256(sshEC521Key) + " jane@example.com (ECDSA)", false},
-		{"Ed25519", args{marshal(sshEDKey, "jane@example.com"), 0}, "256 " + ssh.FingerprintSHA256(sshEDKey) + " jane@example.com (ED25519)", false},
-		{"RSA", args{marshal(sshRSAKey, "jane@example.com"), 0}, "2048 " + ssh.FingerprintSHA256(sshRSAKey) + " jane@example.com (RSA)", false},
-		{"SK-ECDSA", args{marshal(skECKey, "jane@example.com"), 0}, "256 " + ssh.FingerprintSHA256(skECKey) + " jane@example.com (SK-ECDSA)", false},
-		{"SK-ED25519", args{marshal(skEDKey, "jane@example.com"), 0}, "256 " + ssh.FingerprintSHA256(skEDKey) + " jane@example.com (SK-ED25519)", false},
-		{"ED25519-CERT", args{marshal(sshCert, "jane@example.com"), 0}, "256 " + ssh.FingerprintSHA256(sshCert) + " jane@example.com (ED25519-CERT)", false},
-		{"DSA", args{marshal(sshDSAKey, "jane@example.com"), 0}, "1024 " + ssh.FingerprintSHA256(sshDSAKey) + " jane@example.com (DSA)", false},
-		{"Base64RawFingerprint", args{marshal(sshECKey, ""), Base64RawFingerprint}, "256 " + ssh.FingerprintSHA256(sshECKey) + " no comment (ECDSA)", false},
-		{"Base64RawURLFingerprint", args{marshal(sshECKey, ""), Base64RawURLFingerprint}, "256 SHA256:" + base64.RawURLEncoding.EncodeToString(ec256Bytes) + " no comment (ECDSA)", false},
-		{"Base64Fingerprint", args{marshal(sshECKey, ""), Base64Fingerprint}, "256 SHA256:" + base64.StdEncoding.EncodeToString(ec256Bytes) + " no comment (ECDSA)", false},
-		{"Base64UrlFingerprint", args{marshal(sshECKey, ""), Base64URLFingerprint}, "256 SHA256:" + base64.URLEncoding.EncodeToString(ec256Bytes) + " no comment (ECDSA)", false},
-		{"HexFingerprint", args{marshal(sshECKey, ""), HexFingerprint}, "256 SHA256:" + hex.EncodeToString(ec256Bytes) + " no comment (ECDSA)", false},
-		{"EmojiFingerprint", args{marshal(sshECKey, ""), EmojiFingerprint}, "256 SHA256:" + emoji.Emoji(ec256Bytes) + " no comment (ECDSA)", false},
-		{"fail input", args{marshal(sshECKey, "")[:50], EmojiFingerprint}, "", true},
-		{"fail encoding", args{marshal(sshECKey, ""), 100}, "", true},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := FormatFingerprint(tt.args.in, tt.args.encoding)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("FormatFingerprint() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("FormatFingerprint() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-type fakeKey struct {
-	typ   string
-	bytes []byte
-}
-
-func (s *fakeKey) Type() string                                 { return s.typ }
-func (s *fakeKey) Marshal() []byte                              { return s.bytes }
-func (s *fakeKey) Verify(data []byte, sig *ssh.Signature) error { return nil }
-
-type fakeCryptoPublicKey struct {
-	typ   string
-	key   crypto.PublicKey
-	bytes []byte
-}
-
-func (s *fakeCryptoPublicKey) Type() string                                 { return s.typ }
-func (s *fakeCryptoPublicKey) Marshal() []byte                              { return s.bytes }
-func (s *fakeCryptoPublicKey) Verify(data []byte, sig *ssh.Signature) error { return nil }
-func (s *fakeCryptoPublicKey) CryptoPublicKey() crypto.PublicKey            { return s.key }
-
-func Test_publicKeyTypeAndSize_errors(t *testing.T) {
-	ecKey, _ := generateKey(t, "EC", "P-256", 0)
-
-	type args struct {
-		key ssh.PublicKey
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    string
-		want1   int
-		wantErr bool
-	}{
-		{"fail RSA", args{&fakeKey{ssh.KeyAlgoRSA, nil}}, "", 0, true},
-		{"fail DSA", args{&fakeKey{ssh.KeyAlgoDSA, nil}}, "", 0, true},
-		{"fail RSA cast", args{&fakeCryptoPublicKey{ssh.KeyAlgoRSA, ecKey, nil}}, "", 0, true},
-		{"fail DSA cast", args{&fakeCryptoPublicKey{ssh.KeyAlgoDSA, ecKey, nil}}, "", 0, true},
-		{"fail type", args{&fakeKey{"unknown-type", nil}}, "", 0, true},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, got1, err := publicKeyTypeAndSize(tt.args.key)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("publicKeyTypeAndSize() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("publicKeyTypeAndSize() got = %v, want %v", got, tt.want)
-			}
-			if got1 != tt.want1 {
-				t.Errorf("publicKeyTypeAndSize() got1 = %v, want %v", got1, tt.want1)
-			}
-		})
-	}
-}
diff --git a/sshutil/sshutil_test.go b/sshutil/sshutil_test.go
index 2e3b4ed..e94ae7b 100644
--- a/sshutil/sshutil_test.go
+++ b/sshutil/sshutil_test.go
@@ -43,7 +43,7 @@ func generateFakeSKKey(t *testing.T, pub crypto.PublicKey) ssh.PublicKey {
 			ID          string
 			Key         []byte
 			Application string
-		}{"sk-ecdsa-sha2-nistp256@openssh.com", "nistp256", elliptic.Marshal(k.Curve, k.X, k.Y), "ssh"}
+		}{"name", "id", elliptic.Marshal(k.Curve, k.X, k.Y), "ssh"}
 		return &skKey{
 			typ:   "sk-ecdsa-sha2-nistp256@openssh.com",
 			bytes: ssh.Marshal(w),
@@ -53,7 +53,7 @@ func generateFakeSKKey(t *testing.T, pub crypto.PublicKey) ssh.PublicKey {
 			Name        string
 			KeyBytes    []byte
 			Application string
-		}{"sk-ssh-ed25519@openssh.com", []byte(k), "ssh"}
+		}{"name", []byte(k), "ssh"}
 		return &skKey{
 			typ:   "sk-ssh-ed25519@openssh.com",
 			bytes: ssh.Marshal(w),
diff --git a/x509util/certificate_request_test.go b/x509util/certificate_request_test.go
index 6e200e6..dae1826 100644
--- a/x509util/certificate_request_test.go
+++ b/x509util/certificate_request_test.go
@@ -90,7 +90,7 @@ func Test_newCertificateRequest(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := NewCertificateRequestFromX509(tt.args.cr); !reflect.DeepEqual(got, tt.want) {
+			if got := newCertificateRequest(tt.args.cr); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("newCertificateRequest() = %v, want %v", got, tt.want)
 			}
 		})
diff --git a/x509util/certificate_test.go b/x509util/certificate_test.go
index 9bae360..af31ff0 100644
--- a/x509util/certificate_test.go
+++ b/x509util/certificate_test.go
@@ -438,23 +438,23 @@ func TestCreateCertificate(t *testing.T) {
 	}
 
 	cr1, priv1 := createCertificateRequest(t, "commonName", []string{"foo.com"})
-	crt1 := NewCertificateRequestFromX509(cr1).GetLeafCertificate().GetCertificate()
+	crt1 := newCertificateRequest(cr1).GetLeafCertificate().GetCertificate()
 	crt1.SerialNumber = mustSerialNumber()
 	crt1.SubjectKeyId = mustSubjectKeyID(priv1.Public())
 
 	cr2, priv2 := createCertificateRequest(t, "commonName", []string{"foo.com"})
-	crt2 := NewCertificateRequestFromX509(cr2).GetLeafCertificate().GetCertificate()
+	crt2 := newCertificateRequest(cr2).GetLeafCertificate().GetCertificate()
 	crt2.SerialNumber = mustSerialNumber()
 
 	cr3, priv3 := createCertificateRequest(t, "commonName", []string{"foo.com"})
-	crt3 := NewCertificateRequestFromX509(cr3).GetLeafCertificate().GetCertificate()
+	crt3 := newCertificateRequest(cr3).GetLeafCertificate().GetCertificate()
 	crt3.SubjectKeyId = mustSubjectKeyID(priv1.Public())
 
 	cr4, priv4 := createCertificateRequest(t, "commonName", []string{"foo.com"})
-	crt4 := NewCertificateRequestFromX509(cr4).GetLeafCertificate().GetCertificate()
+	crt4 := newCertificateRequest(cr4).GetLeafCertificate().GetCertificate()
 
 	cr5, _ := createCertificateRequest(t, "commonName", []string{"foo.com"})
-	crt5 := NewCertificateRequestFromX509(cr5).GetLeafCertificate().GetCertificate()
+	crt5 := newCertificateRequest(cr5).GetLeafCertificate().GetCertificate()
 
 	badSigner := createBadSigner(t)
 
diff --git a/x509util/extensions_test.go b/x509util/extensions_test.go
index ab6e6ed..f0f9ce4 100644
--- a/x509util/extensions_test.go
+++ b/x509util/extensions_test.go
@@ -409,46 +409,6 @@ func TestKeyUsage_Set(t *testing.T) {
 	}
 }
 
-func TestKeyUsage_MarshalJSON(t *testing.T) {
-	tests := []struct {
-		name    string
-		k       KeyUsage
-		want    string
-		wantErr bool
-	}{
-		{"DigitalSignature", KeyUsage(x509.KeyUsageDigitalSignature), `["digitalsignature"]`, false},
-		{"ContentCommitment", KeyUsage(x509.KeyUsageContentCommitment), `["contentcommitment"]`, false},
-		{"KeyEncipherment", KeyUsage(x509.KeyUsageKeyEncipherment), `["keyencipherment"]`, false},
-		{"DataEncipherment", KeyUsage(x509.KeyUsageDataEncipherment), `["dataencipherment"]`, false},
-		{"KeyAgreement", KeyUsage(x509.KeyUsageKeyAgreement), `["keyagreement"]`, false},
-		{"CertSign", KeyUsage(x509.KeyUsageCertSign), `["certsign"]`, false},
-		{"CRLSign", KeyUsage(x509.KeyUsageCRLSign), `["crlsign"]`, false},
-		{"EncipherOnly", KeyUsage(x509.KeyUsageEncipherOnly), `["encipheronly"]`, false},
-		{"DecipherOnly", KeyUsage(x509.KeyUsageDecipherOnly), `["decipheronly"]`, false},
-		{"DigitalSignature + KeyEncipherment", KeyUsage(x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment), `["digitalsignature","keyencipherment"]`, false},
-		{"Error", KeyUsage(x509.KeyUsageDecipherOnly << 1), "", true},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := tt.k.MarshalJSON()
-			if (err != nil) != tt.wantErr {
-				t.Fatalf("KeyUsage.MarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if tt.wantErr {
-				return
-			}
-			if tt.want != string(got) {
-				t.Errorf("KeyUsage.MarshalJSON() = %q, want %q", string(got), tt.want)
-			}
-			var unmarshaled KeyUsage
-			unmarshaled.UnmarshalJSON(got)
-			if unmarshaled != tt.k {
-				t.Errorf("KeyUsage.UnmarshalJSON(keyUsage.MarshalJSON) = %v, want %v", unmarshaled, tt.k)
-			}
-		})
-	}
-}
-
 func TestKeyUsage_UnmarshalJSON(t *testing.T) {
 	type args struct {
 		data []byte
@@ -531,51 +491,6 @@ func TestExtKeyUsage_Set(t *testing.T) {
 	}
 }
 
-func TestExtKeyUsage_MarshalJSON(t *testing.T) {
-	tests := []struct {
-		name    string
-		eku     ExtKeyUsage
-		want    string
-		wantErr bool
-	}{
-		{"Any", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageAny}), `["any"]`, false},
-		{"ServerAuth", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}), `["serverauth"]`, false},
-		{"ClientAuth", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}), `["clientauth"]`, false},
-		{"CodeSigning", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning}), `["codesigning"]`, false},
-		{"EmailProtection", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}), `["emailprotection"]`, false},
-		{"IPSECEndSystem", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageIPSECEndSystem}), `["ipsecendsystem"]`, false},
-		{"IPSECTunnel", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageIPSECTunnel}), `["ipsectunnel"]`, false},
-		{"IPSECUser", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageIPSECUser}), `["ipsecuser"]`, false},
-		{"TimeStamping", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageTimeStamping}), `["timestamping"]`, false},
-		{"OCSPSigning", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageOCSPSigning}), `["ocspsigning"]`, false},
-		{"MicrosoftServerGatedCrypto", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageMicrosoftServerGatedCrypto}), `["microsoftservergatedcrypto"]`, false},
-		{"NetscapeServerGatedCrypto", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageNetscapeServerGatedCrypto}), `["netscapeservergatedcrypto"]`, false},
-		{"MicrosoftCommercialCodeSigning", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageMicrosoftCommercialCodeSigning}), `["microsoftcommercialcodesigning"]`, false},
-		{"MicrosoftKernelCodeSigning", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageMicrosoftKernelCodeSigning}), `["microsoftkernelcodesigning"]`, false},
-		{"ServerAuth + ClientAuth", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}), `["serverauth","clientauth"]`, false},
-		{"Error", ExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageMicrosoftKernelCodeSigning + 1}), "", true},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := tt.eku.MarshalJSON()
-			if (err != nil) != tt.wantErr {
-				t.Fatalf("ExtKeyUsage.MarshalJSON() = error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if tt.wantErr {
-				return
-			}
-			if tt.want != string(got) {
-				t.Errorf("ExtKeyUsage.MarshalJSON() = %q, want %q", string(got), tt.want)
-			}
-			var unmarshaled ExtKeyUsage
-			unmarshaled.UnmarshalJSON(got)
-			if !reflect.DeepEqual(unmarshaled, tt.eku) {
-				t.Errorf("ExtKeyUsage.UnmarshalJSON(ExtKeyUsage.MarshalJSON) = %v, want %v", unmarshaled, tt.eku)
-			}
-		})
-	}
-}
-
 func TestExtKeyUsage_UnmarshalJSON(t *testing.T) {
 	type args struct {
 		data []byte
diff --git a/x509util/fingerprint_test.go b/x509util/fingerprint_test.go
deleted file mode 100644
index 3126e99..0000000
--- a/x509util/fingerprint_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package x509util
-
-import (
-	"crypto/x509"
-	"testing"
-)
-
-func TestFingerprint(t *testing.T) {
-	ecdsaCrt := decodeCertificateFile(t, "testdata/google.crt")
-	rsaCrt := decodeCertificateFile(t, "testdata/smallstep.crt")
-	ed25519Crt := decodeCertificateFile(t, "testdata/ed25519.crt")
-
-	type args struct {
-		cert *x509.Certificate
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		{"ecdsaCert", args{ecdsaCrt}, "38011621ecdcc2172e933a1ef2317efc535a161c00333aee3f84abfab4e640bf"},
-		{"rsaCert", args{rsaCrt}, "5eeaf6dd1d1f064f6f95c5d74c39ad0abca33bdba59d2844d0b5e6d8453f6c4b"},
-		{"ed25519Cert", args{ed25519Crt}, "047b2fff20997a5009d1b36864af95b03f168c09dc2ed1a71ee36ccf973c9d31"},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := Fingerprint(tt.args.cert); got != tt.want {
-				t.Errorf("Fingerprint() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestEncodedFingerprint(t *testing.T) {
-	ecdsaCrt := decodeCertificateFile(t, "testdata/google.crt")
-
-	type args struct {
-		cert     *x509.Certificate
-		encoding FingerprintEncoding
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		{"default", args{ecdsaCrt, 0}, "38011621ecdcc2172e933a1ef2317efc535a161c00333aee3f84abfab4e640bf"},
-		{"HexFingerprint", args{ecdsaCrt, HexFingerprint}, "38011621ecdcc2172e933a1ef2317efc535a161c00333aee3f84abfab4e640bf"},
-		{"Base64Fingerprint", args{ecdsaCrt, Base64Fingerprint}, "OAEWIezcwhcukzoe8jF+/FNaFhwAMzruP4Sr+rTmQL8="},
-		{"Base64URLFingerprint", args{ecdsaCrt, Base64URLFingerprint}, "OAEWIezcwhcukzoe8jF-_FNaFhwAMzruP4Sr-rTmQL8="},
-		{"Base64RawFingerprint", args{ecdsaCrt, Base64RawFingerprint}, "OAEWIezcwhcukzoe8jF+/FNaFhwAMzruP4Sr+rTmQL8"},
-		{"Base64RawURLFingerprint", args{ecdsaCrt, Base64RawURLFingerprint}, "OAEWIezcwhcukzoe8jF-_FNaFhwAMzruP4Sr-rTmQL8"},
-		{"EmojiFingerprint", args{ecdsaCrt, EmojiFingerprint}, "💨🎱🌼📆🎠🎉🎿🚙🍪🌊♦️💡✌️🐮🔒❌🖕😬🌼👦👍👑♦️🇬🇧👂🔬📌♿🚀🚜🍆🐑"},
-		{"Unknown", args{ecdsaCrt, 100}, ""},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := EncodedFingerprint(tt.args.cert, tt.args.encoding); got != tt.want {
-				t.Errorf("EncodedFingerprint() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/x509util/utils_test.go b/x509util/utils_test.go
index 534b884..67db026 100644
--- a/x509util/utils_test.go
+++ b/x509util/utils_test.go
@@ -143,6 +143,58 @@ func TestCreateSANs(t *testing.T) {
 	}
 }
 
+func TestFingerprint(t *testing.T) {
+	ecdsaCrt := decodeCertificateFile(t, "testdata/google.crt")
+	rsaCrt := decodeCertificateFile(t, "testdata/smallstep.crt")
+	ed25519Crt := decodeCertificateFile(t, "testdata/ed25519.crt")
+
+	type args struct {
+		cert *x509.Certificate
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{"ecdsaCert", args{ecdsaCrt}, "38011621ecdcc2172e933a1ef2317efc535a161c00333aee3f84abfab4e640bf"},
+		{"rsaCert", args{rsaCrt}, "5eeaf6dd1d1f064f6f95c5d74c39ad0abca33bdba59d2844d0b5e6d8453f6c4b"},
+		{"ed25519Cert", args{ed25519Crt}, "047b2fff20997a5009d1b36864af95b03f168c09dc2ed1a71ee36ccf973c9d31"},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := Fingerprint(tt.args.cert); got != tt.want {
+				t.Errorf("Fingerprint() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestEncodedFingerprint(t *testing.T) {
+	ecdsaCrt := decodeCertificateFile(t, "testdata/google.crt")
+
+	type args struct {
+		cert     *x509.Certificate
+		encoding FingerprintEncoding
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{"HexFingerprint", args{ecdsaCrt, HexFingerprint}, "38011621ecdcc2172e933a1ef2317efc535a161c00333aee3f84abfab4e640bf"},
+		{"Base64Fingerprint", args{ecdsaCrt, Base64Fingerprint}, "OAEWIezcwhcukzoe8jF+/FNaFhwAMzruP4Sr+rTmQL8="},
+		{"Base64UrlFingerprint", args{ecdsaCrt, Base64UrlFingerprint}, "OAEWIezcwhcukzoe8jF-_FNaFhwAMzruP4Sr-rTmQL8="},
+		{"Unknown", args{ecdsaCrt, 100}, ""},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := EncodedFingerprint(tt.args.cert, tt.args.encoding); got != tt.want {
+				t.Errorf("EncodedFingerprint() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
 func Test_generateSubjectKeyID(t *testing.T) {
 	ecdsaCrt := decodeCertificateFile(t, "testdata/google.crt")
 	rsaCrt := decodeCertificateFile(t, "testdata/smallstep.crt")