/*
 * mskb2x509cert.c -- extract x509 format certificate from 
 *                    MS IIS Key Backup file
 *
 * Written 11/2003 by William Herrin, herrin@dirtside.com
 * Released to the public domain.
 *
 * Usage:
 *   mskb2mskb2x509cert < keybackup.key > keybackup.x509cert
 *   openssl x509 -text -in keybackup.x509cert -inform DER -out \
 *     keybackup.apachecert
 *
 * Based on the message from David Weiss posted to 
 * focus-ms-help@securityfocus.com on April 1, 2002.
 *
 * Export Key:
 *   Key Manager -> Key -> Backup Keyfile
 *   Save as backup.key
 *
 * Hex Edit:
 *   Open backup.key in Hex Editor
 *   Find first occurance of "private-key", and search back to 30 82
 *   Delete all before 30 82
 *   Save as backup_key.bin
 *
 *   Open backup.key in Hex Editor
 *   Find first occurance of "certificate" followed by 30 82
 *   Delete all before 30 82
 *   Save as backup_cert.bin
 *
 * Convert:
 *   openssl rsa -inform NET -in backup_key.bin -out backup_new.key
 *   openssl x509 -text -in backup_cert.bin -inform DER -out backup_new.crt
 */

#include <stdio.h>
#include <string.h>

int main (int argc, char **argv) {
  char key[100000], code[2];
  size_t l,i,j;

  /* No key backup file should be over 100kbytes. So, load into a buffer
   * in one fell swoop. */
  l = fread (key,1,100000,stdin);

  fprintf (stderr,"read %i bytes\n",l);

  code[0] = 0x30;
  code[1] = 0x82;

  /* Find the first occurance of the string "certificate". Note that
   * in my test files, the first part of the word was cut off. I have no
   * idea why. */
  for (i=0; i<(l-50); i++) if (memcmp(key+i,"tificate",8)==0) {
    /* Search forward for 0x30 0x82. Should be nearby. */
    for (j=i; j<(i+30); j++) if (memcmp(key+j,code,2) ==0){
      /* And save it from that point. */
      fprintf (stderr,"Writing from byte %i\n",j);
      fwrite (key+j,1,l-j,stdout);
      return 0;
    }
  }
  fprintf (stderr,"could not find the right spot\n");
  return 1;
}
