[ 
https://issues.apache.org/jira/browse/SSHD-1266?focusedWorklogId=769010&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-769010
 ]

ASF GitHub Bot logged work on SSHD-1266:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 11/May/22 11:39
            Start Date: 11/May/22 11:39
    Worklog Time Spent: 10m 
      Work Description: vukzeka commented on code in PR #222:
URL: https://github.com/apache/mina-sshd/pull/222#discussion_r870194796


##########
sshd-core/src/main/java/org/apache/sshd/certificate/OpenSshCertificateBuilder.java:
##########
@@ -104,7 +110,21 @@ public OpenSshCertificateBuilder 
principals(Collection<String> principals) {
     }
 
     public OpenSshCertificateBuilder 
criticalOptions(List<OpenSshCertificate.CertificateOption> criticalOptions) {
-        this.criticalOptions = criticalOptions;
+        if (criticalOptions != null && !criticalOptions.isEmpty()) {
+            // check if any duplicates
+            Set<String> names = new HashSet<String>();
+            Set<String> duplicates = criticalOptions.stream().filter(option -> 
!names.add(option.getName()))
+                    .map(option -> option.getName())
+                    .collect(Collectors.toSet());
+            if (!duplicates.isEmpty()) {
+                throw new IllegalArgumentException("Duplicate critical option: 
" + String.join(",", duplicates));
+            }
+            // lexically order by "name"
+            List<OpenSshCertificate.CertificateOption> sortedCriticalOptions = 
criticalOptions.stream()
+                    
.sorted(Comparator.comparing(OpenSshCertificate.CertificateOption::getName))
+                    .collect(Collectors.toList());
+            this.criticalOptions = sortedCriticalOptions;
+        }

Review Comment:
   @tomaswolf I was not aware that duplicate and sorting are applied for 
extensions.
   I just checked with ssh-keygen and is possible to add custom extensions and 
these are not sorted and also duplicates are allowed
   
   for example following
   ```
   ssh-keygen -s user_ca -I certN -n user -O extension:test=value -O 
extension:test=value -O extension:[email protected]=value -O 
extension:[email protected]=value -O critical:b_critical_option=value -O 
critical:a_critical_option=value -V +10d user-key.pub
   ```
   
   would generate
   
   ```Type: [email protected] user certificate
           Public key: RSA-CERT 
SHA256:c6uq2hsYBCROmuFrWz38sIk+0Hlx75l5kOqRo7J1wv8
           Signing CA: RSA SHA256:qBnc5EM9d1dlZSfbtnPBh45cAJt5jM7LcLeGDbFOd38 
(using rsa-sha2-512)
           Key ID: "certN"
           Serial: 0
           Valid: from 2022-05-11T13:24:00 to 2022-05-21T13:25:15
           Principals: 
                   user
           Critical Options: (none)
           Extensions: 
                   permit-X11-forwarding
                   permit-agent-forwarding
                   permit-port-forwarding
                   permit-pty
                   permit-user-rc
                   test UNKNOWN OPTION (len 9)
                   test UNKNOWN OPTION (len 9)
                   [email protected] UNKNOWN OPTION (len 9)
                   [email protected] UNKNOWN OPTION (len 9)
   ```
   
   So it looks to me
   
   - duplicates are checked only for standard extensions
   - ordering is applied only for standard extensions
   - all custom extensions are added in the order as specified and custom 
duplicates are allowed
   
   @tomaswolf I can add like that if that sounds correct?





Issue Time Tracking
-------------------

    Worklog Id:     (was: 769010)
    Time Spent: 2h  (was: 1h 50m)

> OpenSSH certificate is not properly encoded when critical options are included
> ------------------------------------------------------------------------------
>
>                 Key: SSHD-1266
>                 URL: https://issues.apache.org/jira/browse/SSHD-1266
>             Project: MINA SSHD
>          Issue Type: Bug
>    Affects Versions: 2.8.0
>            Reporter: Zeljko Vukovic
>            Priority: Minor
>          Time Spent: 2h
>  Remaining Estimate: 0h
>
> If critical options are included when OpenSSH certificate is created same 
> can't be read with OpenSSH.
>  
> In oder to reproduce issue we can use existing test 
> [https://github.com/apache/mina-sshd/blob/master/sshd-core/src/test/java/org/apache/sshd/certificates/GenerateOpenSSHClientCertificateTest.java#L152]
>  and just add critical options (as in the example bellow)
> {code:java}
> final OpenSshCertificate signedCert = 
> OpenSshCertificateBuilder.userCertificate()
>                .serial(0L)                
>                .publicKey(clientPublicKey)                
>                .id("user01")                
>                .principals(Collections.singletonList("user01"))               
>  
>                .criticalOptions(Arrays.asList(
>                         new 
> OpenSshCertificate.CertificateOption("force-command", "wget url"),
>                         new 
> OpenSshCertificate.CertificateOption("source-address", "127.0.0.1/32")))      
>     
>                .extensions(Arrays.asList(
>                         new 
> OpenSshCertificate.CertificateOption("permit-X11-forwarding"),
>                         new 
> OpenSshCertificate.CertificateOption("permit-agent-forwarding"),
>                         new 
> OpenSshCertificate.CertificateOption("permit-port-forwarding"),
>                         new 
> OpenSshCertificate.CertificateOption("permit-pty"),
>                         new 
> OpenSshCertificate.CertificateOption("permit-user-rc")))
>                 .sign(caKeypair, signatureAlgorithm); {code}
>  
> Once we check such certificate we get following error 
> {code:java}
> > ssh-keygen -L -f  /path/to/cert.pub 
> Type: [email protected] user certificate
>         Public key: ECDSA-CERT 
> SHA256:0ITcONLKI/H/FNpXZVZMaEYB0STXD4BQNBkSSuDpk5U
>         Signing CA: ECDSA SHA256:KPz5LunqQBL9hWJx5eDk11T16anJCn40d/g480PfuKw 
> (using ecdsa-sha2-nistp384)
>         Key ID: "user01"
>         Serial: 0
>         Valid: forever
>         Principals: 
>                 user01
>         Critical Options: 
> show_options: buffer error: string is too large {code}
> and similar for the other cert types(RSA, EC, Ed25519).
> I was tracing this issue and it looks like related to this code 
> [https://github.com/apache/mina-sshd/blob/master/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java#L840]
>  but I was not able to figure out what exactly.  
>  
> Interesting is that parsing certificate is working as expected 
> [https://github.com/apache/mina-sshd/blob/master/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java#L370]
> from code but also even if I create certificate directly with ssh-keygen
> {code:java}
> ssh-keygen -t rsa -b 4096 -f user_ca -C user_ca
> ssh-keygen -f user-key -b 4096 -t rsa
> ssh-keygen -s user_ca -I certN -n user -O source-address="127.0.0.1/32" -O 
> force-command="wget url" -V +10d user-key.pub {code}
>  
> [[email protected]] / [~twolf]  please if any hints what to check(it 
> looks to me that there is something wrong with encoding certificate option 
> data 
> [https://github.com/apache/mina-sshd/blob/master/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java#L838-L845]
>  , like these tuples should be written somehow differently) I am more than 
> open to support and create PR.
> This is working as expected for extensions as these are all empty(do not have 
> data) but once we include critical options which have data than there is 
> mentioned failure 
> ([https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys#L221-L268]
>  ).
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to