- if (silc_buffer_format(&sig,
- SILC_STR_UI_INT(strlen(name)),
- SILC_STR_UI32_STRING(name),
- SILC_STR_UI_INT(signature_len),
- SILC_STR_DATA(signature, signature_len),
- SILC_STR_END) < 0) {
- silc_free(sign);
- sign->sign_cb(FALSE, NULL, 0, sign->context);
+
+ /* Format the signature. RSA is easy because PKCS#1 is already in
+ correct format. For DSA the returned signature is in PKIX compliant
+ format and we have reformat it for SSH2. */
+ if (!strcmp(sign->privkey->pkcs->name, "dsa")) {
+ asn1 = silc_asn1_alloc(stack);
+ if (!asn1) {
+ sign->sign_cb(FALSE, NULL, 0, sign->context);
+ silc_sfree(stack, sign);
+ silc_stack_free(stack);
+ return;
+ }
+
+ /* Decode the signature */
+ silc_buffer_set(&sig, (unsigned char *)signature, signature_len);
+ if (!silc_asn1_decode(asn1, &sig,
+ SILC_ASN1_SEQUENCE,
+ SILC_ASN1_INT(&r),
+ SILC_ASN1_INT(&s),
+ SILC_ASN1_END, SILC_ASN1_END)) {
+ sign->sign_cb(FALSE, NULL, 0, sign->context);
+ silc_asn1_free(asn1);
+ silc_sfree(stack, sign);
+ silc_stack_free(stack);
+ return;
+ }
+
+ /* Encode the integers */
+ memset(rbuf, 0, sizeof(rbuf));
+ memset(sbuf, 0, sizeof(sbuf));
+ silc_mp_mp2bin_noalloc(&r, rbuf, sizeof(rbuf));
+ silc_mp_mp2bin_noalloc(&s, sbuf, sizeof(sbuf));
+
+ silc_asn1_free(asn1);
+
+ /* Encode SSH2 DSS signature */
+ if (silc_buffer_sformat(stack, &sig,
+ SILC_STR_UI_INT(7),
+ SILC_STR_UI32_STRING("ssh-dss"),
+ SILC_STR_UI_INT(sizeof(rbuf) + sizeof(sbuf)),
+ SILC_STR_DATA(rbuf, sizeof(rbuf)),
+ SILC_STR_DATA(sbuf, sizeof(sbuf)),
+ SILC_STR_END) < 0) {
+ sign->sign_cb(FALSE, NULL, 0, sign->context);
+ silc_sfree(stack, sign);
+ silc_stack_free(stack);
+ return;
+ }
+ } else {
+ /* Encode SSH2 RSA signature */
+ if (silc_buffer_sformat(stack, &sig,
+ SILC_STR_UI_INT(7),
+ SILC_STR_UI32_STRING("ssh-rsa"),
+ SILC_STR_UI_INT(signature_len),
+ SILC_STR_DATA(signature, signature_len),
+ SILC_STR_END) < 0) {
+ sign->sign_cb(FALSE, NULL, 0, sign->context);
+ silc_sfree(stack, sign);
+ silc_stack_free(stack);
+ return;
+ }