limit-keytype.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. # $OpenBSD: limit-keytype.sh,v 1.9 2019/12/16 02:39:05 djm Exp $
  2. # Placed in the Public Domain.
  3. tid="restrict pubkey type"
  4. # XXX sk-* keys aren't actually tested ATM.
  5. rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key*
  6. rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key*
  7. mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
  8. mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig
  9. ktype1=ed25519
  10. ktype2=ed25519
  11. ktype3=ed25519
  12. ktype4=ed25519
  13. ktype5=ed25519
  14. ktype6=ed25519
  15. for t in $SSH_KEYTYPES; do
  16. case "$t" in
  17. ssh-rsa) ktype2=rsa ;;
  18. ecdsa*) ktype3=ecdsa ;; # unused
  19. ssh-dss) ktype4=dsa ;;
  20. sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;;
  21. sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;;
  22. esac
  23. done
  24. # Create a CA key
  25. ${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_ca_key ||
  26. fatal "ssh-keygen failed"
  27. # Make some keys and a certificate.
  28. ${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_key1 ||
  29. fatal "ssh-keygen failed"
  30. ${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key2 ||
  31. fatal "ssh-keygen failed"
  32. ${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key3 ||
  33. fatal "ssh-keygen failed"
  34. ${SSHKEYGEN} -q -N '' -t $ktype4 -f $OBJ/user_key4 ||
  35. fatal "ssh-keygen failed"
  36. ${SSHKEYGEN} -q -N '' -t $ktype5 -f $OBJ/user_key5 ||
  37. fatal "ssh-keygen failed"
  38. ${SSHKEYGEN} -q -N '' -t $ktype6 -f $OBJ/user_key6 ||
  39. fatal "ssh-keygen failed"
  40. ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \
  41. -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 ||
  42. fatal "couldn't sign user_key1"
  43. # Copy the private key alongside the cert to allow better control of when
  44. # it is offered.
  45. mv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub
  46. grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy
  47. opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes"
  48. certopts="$opts -i $OBJ/user_key3 -oCertificateFile=$OBJ/cert_user_key3.pub"
  49. echo mekmitasdigoat > $OBJ/authorized_principals_$USER
  50. cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER
  51. cat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER
  52. prepare_config()
  53. {
  54. (
  55. grep -v "Protocol" $OBJ/sshd_proxy.orig
  56. echo "Protocol 2"
  57. echo "AuthenticationMethods publickey"
  58. echo "TrustedUserCAKeys $OBJ/user_ca_key.pub"
  59. echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
  60. for x in "$@"; do
  61. echo "$x"
  62. done
  63. ) > $OBJ/sshd_proxy
  64. }
  65. # Return the required parameter for PubkeyAcceptedKeyAlgorithms corresponding to
  66. # the supplied key type.
  67. keytype()
  68. {
  69. case "$1" in
  70. ecdsa) printf "ecdsa-sha2-*" ;;
  71. ed25519) printf "ssh-ed25519" ;;
  72. dsa) printf "ssh-dss" ;;
  73. rsa) printf "rsa-sha2-256,rsa-sha2-512,ssh-rsa" ;;
  74. sk-ecdsa) printf "sk-ecdsa-*" ;;
  75. sk-ssh-ed25519) printf "sk-ssh-ed25519-*" ;;
  76. esac
  77. }
  78. prepare_config
  79. # Check we can log in with all key types.
  80. ${SSH} $certopts proxy true || fatal "cert failed"
  81. ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
  82. ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
  83. # Allow plain Ed25519 and RSA. The certificate should fail.
  84. verbose "allow $ktype2,$ktype1"
  85. prepare_config \
  86. "PubkeyAcceptedKeyAlgorithms $(keytype $ktype2),$(keytype $ktype1)"
  87. ${SSH} $certopts proxy true && fatal "cert succeeded"
  88. ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
  89. ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
  90. # Allow Ed25519 only.
  91. verbose "allow $ktype1"
  92. prepare_config "PubkeyAcceptedKeyAlgorithms $(keytype $ktype1)"
  93. ${SSH} $certopts proxy true && fatal "cert succeeded"
  94. ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
  95. if [ "$ktype1" != "$ktype2" ]; then
  96. ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded"
  97. fi
  98. # Allow all certs. Plain keys should fail.
  99. verbose "allow cert only"
  100. prepare_config "PubkeyAcceptedKeyAlgorithms *-cert-v01@openssh.com"
  101. ${SSH} $certopts proxy true || fatal "cert failed"
  102. ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
  103. ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded"
  104. # Allow RSA in main config, Ed25519 for non-existent user.
  105. verbose "match w/ no match"
  106. prepare_config "PubkeyAcceptedKeyAlgorithms $(keytype $ktype2)" \
  107. "Match user x$USER" "PubkeyAcceptedKeyAlgorithms +$(keytype $ktype1)"
  108. ${SSH} $certopts proxy true && fatal "cert succeeded"
  109. if [ "$ktype1" != "$ktype2" ]; then
  110. ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
  111. fi
  112. ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
  113. # Allow only DSA in main config, Ed25519 for user.
  114. verbose "match w/ matching"
  115. prepare_config "PubkeyAcceptedKeyAlgorithms $(keytype $ktype4)" \
  116. "Match user $USER" "PubkeyAcceptedKeyAlgorithms +$(keytype $ktype1)"
  117. ${SSH} $certopts proxy true || fatal "cert failed"
  118. ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
  119. ${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded"