async function makeCertAndKey(original) {
  var transport = transportType(original);
  if (transport !== null) {
    if (transport.length != 2) {
      throw Error('bad extension length');
    }
    if (transport[0] < 3) {
      throw Error('too many bits set');  // Only 5 bits are defined.
    }
  }

  const keyalg = {name: 'ECDSA', namedCurve: 'P-256'};
  const keypair =
      await crypto.subtle.generateKey(keyalg, true, ['sign', 'verify']);
  const publicKey = await crypto.subtle.exportKey('raw', keypair.publicKey);
  var serialBuffer = new ArrayBuffer(10);
  var serial = new Uint8Array(serialBuffer);
  crypto.getRandomValues(serial);

  const ecdsaWithSHA256 = [1, 2, 840, 10045, 4, 3, 2];
  const ansiX962 = [1, 2, 840, 10045, 2, 1];
  const secp256R1 = [1, 2, 840, 10045, 3, 1, 7];
  const commonName = [2, 5, 4, 3];
  const x509V3 = 2;

  const certBuilder = new ByteBuilder();
  certBuilder.addASN1(Tag.SEQUENCE, (b) => {
    b.addASN1(Tag.SEQUENCE, (b) => {  // TBSCertificate
      b.addASN1(Tag.CONTEXT_SPECIFIC | Tag.CONSTRUCTED | 0, (b) => {
        b.addASN1Int(x509V3);  // Version
      });
      b.addASN1BigInt(serial);          // Serial number
      b.addASN1(Tag.SEQUENCE, (b) => {  // Signature algorithm
        b.addASN1ObjectIdentifier(ecdsaWithSHA256);
      });
      b.addASN1(Tag.SEQUENCE, (b) => {  // Issuer
        b.addASN1(Tag.SET, (b) => {
          b.addASN1(Tag.SEQUENCE, (b) => {
            b.addASN1ObjectIdentifier(commonName);
            b.addASN1PrintableString('U2F Issuer');
          });
        });
      });
      b.addASN1(Tag.SEQUENCE, (b) => {  // Validity
        b.addASN1(Tag.UTCTime, (b) => {
          b.addBytesFromString('0001010000Z');
        });
        b.addASN1(Tag.UTCTime, (b) => {
          b.addBytesFromString('0001010000Z');
        });
      });
      b.addASN1(Tag.SEQUENCE, (b) => {  // Subject
        b.addASN1(Tag.SET, (b) => {
          b.addASN1(Tag.SEQUENCE, (b) => {
            b.addASN1ObjectIdentifier(commonName);
            b.addASN1PrintableString('U2F Device');
          });
        });
      });
      b.addASN1(Tag.SEQUENCE, (b) => {    // Public key
        b.addASN1(Tag.SEQUENCE, (b) => {  // Algorithm identifier
          b.addASN1ObjectIdentifier(ansiX962);
          b.addASN1ObjectIdentifier(secp256R1);
        });
        b.addASN1BitString(new Uint8Array(publicKey));
      });
      if (transport !== null) {
        var t = transport;  // This causes the compiler to see t cannot be null.
        // Extensions
        b.addASN1(Tag.CONTEXT_SPECIFIC | Tag.CONSTRUCTED | 3, (b) => {
          b.addASN1(Tag.SEQUENCE, (b) => {
            b.addASN1(Tag.SEQUENCE, (b) => {  // Transport-type extension.
              b.addASN1ObjectIdentifier(transportTypeOID);
              b.addASN1(Tag.OCTETSTRING, (b) => {
                b.addASN1(Tag.BITSTRING, (b) => {
                  b.addBytes(t);
                });
              });
            });
          });
        });
      }
    });
    b.addASN1(Tag.SEQUENCE, (b) => {  // Algorithm identifier
      b.addASN1ObjectIdentifier(ecdsaWithSHA256);
    });
    b.addASN1(Tag.BITSTRING, (b) => {  // Signature
      // This signature is obviously not correct since it's constant and the
      // rest of the certificate is not. However, since the issuer certificate
      // doesn't exist, there's no way for anyone to check the signature on this
      // certificate and thus this sufficies. However, at least fastmail.com
      // expects to be able to parse out a valid ECDSA signature and so one is
      // provided.
      b.addBytes(new Uint8Array([
        0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xc1, 0xa3, 0xa6, 0x8e, 0x2f,
        0x16, 0xa7, 0x21, 0x46, 0x27, 0x05, 0x7f, 0x62, 0xbb, 0x72, 0x8c,
        0x9e, 0x03, 0xe7, 0xa1, 0xba, 0x62, 0xd0, 0x46, 0x52, 0x4e, 0x45,
        0x6d, 0x2c, 0x2f, 0x3f, 0x73, 0x02, 0x20, 0x0b, 0x5f, 0x78, 0xe5,
        0x11, 0xaa, 0x18, 0x12, 0x9f, 0x6f, 0x23, 0x6d, 0x92, 0x13, 0x22,
        0x7d, 0x92, 0xb4, 0xe6, 0x7e, 0xdf, 0x53, 0xe8, 0x16, 0xdf, 0xb0,
        0x5d, 0x9d, 0xc8, 0xb9, 0x0f, 0xde
      ]));
    });
  });
  return {privateKey: keypair.privateKey, certDER: certBuilder.data};
}
/**
 * makeCertAndKey creates a new ECDSA keypair and returns the private key
 * and a cert containing the public key.
 *
 * @param {!Uint8Array} original The certificate being replaced, as DER bytes.
 * @return {Promise<{privateKey: !webCrypto.CryptoKey, certDER: !Uint8Array}>}
 */
makeCertAndKey creates a new ECDSA keypair and returns the private key
and a cert containing the public key.

@param {!Uint8Array} original The certificate being replaced, as DER bytes.
makeCertAndKey creates a new ECDSA keypair and returns the private key and a cert containing the public key . @param { !Uint8Array } original The certificate being replaced as DER bytes .
async function makeCertAndKey(original) {
  var transport = transportType(original);
  if (transport !== null) {
    if (transport.length != 2) {
      throw Error('bad extension length');
    }
    if (transport[0] < 3) {
      throw Error('too many bits set');  
    }
  }
  const keyalg = {name: 'ECDSA', namedCurve: 'P-256'};
  const keypair =
      await crypto.subtle.generateKey(keyalg, true, ['sign', 'verify']);
  const publicKey = await crypto.subtle.exportKey('raw', keypair.publicKey);
  var serialBuffer = new ArrayBuffer(10);
  var serial = new Uint8Array(serialBuffer);
  crypto.getRandomValues(serial);
  const ecdsaWithSHA256 = [1, 2, 840, 10045, 4, 3, 2];
  const ansiX962 = [1, 2, 840, 10045, 2, 1];
  const secp256R1 = [1, 2, 840, 10045, 3, 1, 7];
  const commonName = [2, 5, 4, 3];
  const x509V3 = 2;
  const certBuilder = new ByteBuilder();
  certBuilder.addASN1(Tag.SEQUENCE, (b) => {
    b.addASN1(Tag.SEQUENCE, (b) => {  
      b.addASN1(Tag.CONTEXT_SPECIFIC | Tag.CONSTRUCTED | 0, (b) => {
        b.addASN1Int(x509V3);  
      });
      b.addASN1BigInt(serial);          
      b.addASN1(Tag.SEQUENCE, (b) => {  
        b.addASN1ObjectIdentifier(ecdsaWithSHA256);
      });
      b.addASN1(Tag.SEQUENCE, (b) => {  
        b.addASN1(Tag.SET, (b) => {
          b.addASN1(Tag.SEQUENCE, (b) => {
            b.addASN1ObjectIdentifier(commonName);
            b.addASN1PrintableString('U2F Issuer');
          });
        });
      });
      b.addASN1(Tag.SEQUENCE, (b) => {  
        b.addASN1(Tag.UTCTime, (b) => {
          b.addBytesFromString('0001010000Z');
        });
        b.addASN1(Tag.UTCTime, (b) => {
          b.addBytesFromString('0001010000Z');
        });
      });
      b.addASN1(Tag.SEQUENCE, (b) => {  
        b.addASN1(Tag.SET, (b) => {
          b.addASN1(Tag.SEQUENCE, (b) => {
            b.addASN1ObjectIdentifier(commonName);
            b.addASN1PrintableString('U2F Device');
          });
        });
      });
      b.addASN1(Tag.SEQUENCE, (b) => {    
        b.addASN1(Tag.SEQUENCE, (b) => {  
          b.addASN1ObjectIdentifier(ansiX962);
          b.addASN1ObjectIdentifier(secp256R1);
        });
        b.addASN1BitString(new Uint8Array(publicKey));
      });
      if (transport !== null) {
        var t = transport;  
        b.addASN1(Tag.CONTEXT_SPECIFIC | Tag.CONSTRUCTED | 3, (b) => {
          b.addASN1(Tag.SEQUENCE, (b) => {
            b.addASN1(Tag.SEQUENCE, (b) => {  
              b.addASN1ObjectIdentifier(transportTypeOID);
              b.addASN1(Tag.OCTETSTRING, (b) => {
                b.addASN1(Tag.BITSTRING, (b) => {
                  b.addBytes(t);
                });
              });
            });
          });
        });
      }
    });
    b.addASN1(Tag.SEQUENCE, (b) => {  
      b.addASN1ObjectIdentifier(ecdsaWithSHA256);
    });
    b.addASN1(Tag.BITSTRING, (b) => {  
      b.addBytes(new Uint8Array([
        0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xc1, 0xa3, 0xa6, 0x8e, 0x2f,
        0x16, 0xa7, 0x21, 0x46, 0x27, 0x05, 0x7f, 0x62, 0xbb, 0x72, 0x8c,
        0x9e, 0x03, 0xe7, 0xa1, 0xba, 0x62, 0xd0, 0x46, 0x52, 0x4e, 0x45,
        0x6d, 0x2c, 0x2f, 0x3f, 0x73, 0x02, 0x20, 0x0b, 0x5f, 0x78, 0xe5,
        0x11, 0xaa, 0x18, 0x12, 0x9f, 0x6f, 0x23, 0x6d, 0x92, 0x13, 0x22,
        0x7d, 0x92, 0xb4, 0xe6, 0x7e, 0xdf, 0x53, 0xe8, 0x16, 0xdf, 0xb0,
        0x5d, 0x9d, 0xc8, 0xb9, 0x0f, 0xde
      ]));
    });
  });
  return {privateKey: keypair.privateKey, certDER: certBuilder.data};
}
async function makeCertAndKey ( original ) { var transport = transportType ( original ) ; if ( transport !== null ) { if ( transport . length != 2 ) { throw Error ( 'bad extension length' ) ; } if ( transport [ 0 ] < 3 ) { throw Error ( 'too many bits set' ) ; } } const keyalg = { name : 'ECDSA' , namedCurve : 'P-256' } ; const keypair = await crypto . subtle . generateKey ( keyalg , true , [ 'sign' , 'verify' ] ) ; const publicKey = await crypto . subtle . exportKey ( 'raw' , keypair . publicKey ) ; var serialBuffer = new ArrayBuffer ( 10 ) ; var serial = new Uint8Array ( serialBuffer ) ; crypto . getRandomValues ( serial ) ; const ecdsaWithSHA256 = [ 1 , 2 , 840 , 10045 , 4 , 3 , 2 ] ; const ansiX962 = [ 1 , 2 , 840 , 10045 , 2 , 1 ] ; const secp256R1 = [ 1 , 2 , 840 , 10045 , 3 , 1 , 7 ] ; const commonName = [ 2 , 5 , 4 , 3 ] ; const x509V3 = 2 ; const certBuilder = new ByteBuilder ( ) ; certBuilder . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1 ( Tag . CONTEXT_SPECIFIC | Tag . CONSTRUCTED | 0 , ( b ) => { b . addASN1Int ( x509V3 ) ; } ) ; b . addASN1BigInt ( serial ) ; b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1ObjectIdentifier ( ecdsaWithSHA256 ) ; } ) ; b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1 ( Tag . SET , ( b ) => { b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1ObjectIdentifier ( commonName ) ; b . addASN1PrintableString ( 'U2F Issuer' ) ; } ) ; } ) ; } ) ; b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1 ( Tag . UTCTime , ( b ) => { b . addBytesFromString ( '0001010000Z' ) ; } ) ; b . addASN1 ( Tag . UTCTime , ( b ) => { b . addBytesFromString ( '0001010000Z' ) ; } ) ; } ) ; b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1 ( Tag . SET , ( b ) => { b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1ObjectIdentifier ( commonName ) ; b . addASN1PrintableString ( 'U2F Device' ) ; } ) ; } ) ; } ) ; b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1ObjectIdentifier ( ansiX962 ) ; b . addASN1ObjectIdentifier ( secp256R1 ) ; } ) ; b . addASN1BitString ( new Uint8Array ( publicKey ) ) ; } ) ; if ( transport !== null ) { var t = transport ; b . addASN1 ( Tag . CONTEXT_SPECIFIC | Tag . CONSTRUCTED | 3 , ( b ) => { b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1ObjectIdentifier ( transportTypeOID ) ; b . addASN1 ( Tag . OCTETSTRING , ( b ) => { b . addASN1 ( Tag . BITSTRING , ( b ) => { b . addBytes ( t ) ; } ) ; } ) ; } ) ; } ) ; } ) ; } } ) ; b . addASN1 ( Tag . SEQUENCE , ( b ) => { b . addASN1ObjectIdentifier ( ecdsaWithSHA256 ) ; } ) ; b . addASN1 ( Tag . BITSTRING , ( b ) => { b . addBytes ( new Uint8Array ( [ 0x00 , 0x30 , 0x45 , 0x02 , 0x21 , 0x00 , 0xc1 , 0xa3 , 0xa6 , 0x8e , 0x2f , 0x16 , 0xa7 , 0x21 , 0x46 , 0x27 , 0x05 , 0x7f , 0x62 , 0xbb , 0x72 , 0x8c , 0x9e , 0x03 , 0xe7 , 0xa1 , 0xba , 0x62 , 0xd0 , 0x46 , 0x52 , 0x4e , 0x45 , 0x6d , 0x2c , 0x2f , 0x3f , 0x73 , 0x02 , 0x20 , 0x0b , 0x5f , 0x78 , 0xe5 , 0x11 , 0xaa , 0x18 , 0x12 , 0x9f , 0x6f , 0x23 , 0x6d , 0x92 , 0x13 , 0x22 , 0x7d , 0x92 , 0xb4 , 0xe6 , 0x7e , 0xdf , 0x53 , 0xe8 , 0x16 , 0xdf , 0xb0 , 0x5d , 0x9d , 0xc8 , 0xb9 , 0x0f , 0xde ] ) ) ; } ) ; } ) ; return { privateKey : keypair . privateKey , certDER : certBuilder . data } ; }
makeCertAndKey creates a new ECDSA keypair and returns the private key
 and a cert containing the public key.
makeCertAndKey creates a new ECDSA keypair and returns the private key and a cert containing the public key .
// Only 5 bits are defined. // TBSCertificate // Version // Serial number // Signature algorithm // Issuer // Validity // Subject // Public key // Algorithm identifier // This causes the compiler to see t cannot be null. // Extensions // Transport-type extension. // Algorithm identifier // Signature // This signature is obviously not correct since it's constant and the // rest of the certificate is not. However, since the issuer certificate // doesn't exist, there's no way for anyone to check the signature on this // certificate and thus this sufficies. However, at least fastmail.com // expects to be able to parse out a valid ECDSA signature and so one is // provided.