1e1051a39Sopenharmony_ci#! /usr/bin/env perl 2e1051a39Sopenharmony_ci# Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci# 4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci# this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci 9e1051a39Sopenharmony_ci# Perl script to run tests against S/MIME examples in RFC4134 10e1051a39Sopenharmony_ci# Assumes RFC is in current directory and called "rfc4134.txt" 11e1051a39Sopenharmony_ci 12e1051a39Sopenharmony_ciuse MIME::Base64; 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_cimy $badttest = 0; 15e1051a39Sopenharmony_cimy $verbose = 1; 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_cimy $cmscmd; 18e1051a39Sopenharmony_cimy $exdir = "./"; 19e1051a39Sopenharmony_cimy $exfile = "./rfc4134.txt"; 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ciif (-f "../apps/openssl") 22e1051a39Sopenharmony_ci { 23e1051a39Sopenharmony_ci $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms"; 24e1051a39Sopenharmony_ci } 25e1051a39Sopenharmony_cielsif (-f "..\\out32dll\\openssl.exe") 26e1051a39Sopenharmony_ci { 27e1051a39Sopenharmony_ci $cmscmd = "..\\out32dll\\openssl.exe cms"; 28e1051a39Sopenharmony_ci } 29e1051a39Sopenharmony_cielsif (-f "..\\out32\\openssl.exe") 30e1051a39Sopenharmony_ci { 31e1051a39Sopenharmony_ci $cmscmd = "..\\out32\\openssl.exe cms"; 32e1051a39Sopenharmony_ci } 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_cimy @test_list = ( 35e1051a39Sopenharmony_ci [ "3.1.bin" => "dataout" ], 36e1051a39Sopenharmony_ci [ "3.2.bin" => "encode, dataout" ], 37e1051a39Sopenharmony_ci [ "4.1.bin" => "encode, verifyder, cont, dss" ], 38e1051a39Sopenharmony_ci [ "4.2.bin" => "encode, verifyder, cont, rsa" ], 39e1051a39Sopenharmony_ci [ "4.3.bin" => "encode, verifyder, cont_extern, dss" ], 40e1051a39Sopenharmony_ci [ "4.4.bin" => "encode, verifyder, cont, dss" ], 41e1051a39Sopenharmony_ci [ "4.5.bin" => "verifyder, cont, rsa" ], 42e1051a39Sopenharmony_ci [ "4.6.bin" => "encode, verifyder, cont, dss" ], 43e1051a39Sopenharmony_ci [ "4.7.bin" => "encode, verifyder, cont, dss" ], 44e1051a39Sopenharmony_ci [ "4.8.eml" => "verifymime, dss" ], 45e1051a39Sopenharmony_ci [ "4.9.eml" => "verifymime, dss" ], 46e1051a39Sopenharmony_ci [ "4.10.bin" => "encode, verifyder, cont, dss" ], 47e1051a39Sopenharmony_ci [ "4.11.bin" => "encode, certsout" ], 48e1051a39Sopenharmony_ci [ "5.1.bin" => "encode, envelopeder, cont" ], 49e1051a39Sopenharmony_ci [ "5.2.bin" => "encode, envelopeder, cont" ], 50e1051a39Sopenharmony_ci [ "5.3.eml" => "envelopemime, cont" ], 51e1051a39Sopenharmony_ci [ "6.0.bin" => "encode, digest, cont" ], 52e1051a39Sopenharmony_ci [ "7.1.bin" => "encode, encrypted, cont" ], 53e1051a39Sopenharmony_ci [ "7.2.bin" => "encode, encrypted, cont" ] 54e1051a39Sopenharmony_ci); 55e1051a39Sopenharmony_ci 56e1051a39Sopenharmony_ci# Extract examples from RFC4134 text. 57e1051a39Sopenharmony_ci# Base64 decode all examples, certificates and 58e1051a39Sopenharmony_ci# private keys are converted to PEM format. 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_cimy ( $filename, $data ); 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_cimy @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" ); 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci$data = ""; 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ciopen( IN, $exfile ) || die "Can't Open RFC examples file $exfile"; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ciwhile (<IN>) { 69e1051a39Sopenharmony_ci next unless (/^\|/); 70e1051a39Sopenharmony_ci s/^\|//; 71e1051a39Sopenharmony_ci next if (/^\*/); 72e1051a39Sopenharmony_ci if (/^>(.*)$/) { 73e1051a39Sopenharmony_ci $filename = $1; 74e1051a39Sopenharmony_ci next; 75e1051a39Sopenharmony_ci } 76e1051a39Sopenharmony_ci if (/^</) { 77e1051a39Sopenharmony_ci $filename = "$exdir/$filename"; 78e1051a39Sopenharmony_ci if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) { 79e1051a39Sopenharmony_ci $data = decode_base64($data); 80e1051a39Sopenharmony_ci open OUT, ">$filename"; 81e1051a39Sopenharmony_ci binmode OUT; 82e1051a39Sopenharmony_ci print OUT $data; 83e1051a39Sopenharmony_ci close OUT; 84e1051a39Sopenharmony_ci push @cleanup, $filename; 85e1051a39Sopenharmony_ci } 86e1051a39Sopenharmony_ci elsif ( $filename =~ /\.cer$/ ) { 87e1051a39Sopenharmony_ci write_pem( $filename, "CERTIFICATE", $data ); 88e1051a39Sopenharmony_ci } 89e1051a39Sopenharmony_ci elsif ( $filename =~ /\.pri$/ ) { 90e1051a39Sopenharmony_ci write_pem( $filename, "PRIVATE KEY", $data ); 91e1051a39Sopenharmony_ci } 92e1051a39Sopenharmony_ci $data = ""; 93e1051a39Sopenharmony_ci $filename = ""; 94e1051a39Sopenharmony_ci } 95e1051a39Sopenharmony_ci else { 96e1051a39Sopenharmony_ci $data .= $_; 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ci} 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_cimy $secretkey = 102e1051a39Sopenharmony_ci "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32"; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ciforeach (@test_list) { 105e1051a39Sopenharmony_ci my ( $file, $tlist ) = @$_; 106e1051a39Sopenharmony_ci print "Example file $file:\n"; 107e1051a39Sopenharmony_ci if ( $tlist =~ /encode/ ) { 108e1051a39Sopenharmony_ci run_reencode_test( $exdir, $file ); 109e1051a39Sopenharmony_ci } 110e1051a39Sopenharmony_ci if ( $tlist =~ /certsout/ ) { 111e1051a39Sopenharmony_ci run_certsout_test( $exdir, $file ); 112e1051a39Sopenharmony_ci } 113e1051a39Sopenharmony_ci if ( $tlist =~ /dataout/ ) { 114e1051a39Sopenharmony_ci run_dataout_test( $exdir, $file ); 115e1051a39Sopenharmony_ci } 116e1051a39Sopenharmony_ci if ( $tlist =~ /verify/ ) { 117e1051a39Sopenharmony_ci run_verify_test( $exdir, $tlist, $file ); 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci if ( $tlist =~ /digest/ ) { 120e1051a39Sopenharmony_ci run_digest_test( $exdir, $tlist, $file ); 121e1051a39Sopenharmony_ci } 122e1051a39Sopenharmony_ci if ( $tlist =~ /encrypted/ ) { 123e1051a39Sopenharmony_ci run_encrypted_test( $exdir, $tlist, $file, $secretkey ); 124e1051a39Sopenharmony_ci } 125e1051a39Sopenharmony_ci if ( $tlist =~ /envelope/ ) { 126e1051a39Sopenharmony_ci run_envelope_test( $exdir, $tlist, $file ); 127e1051a39Sopenharmony_ci } 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci} 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ciforeach (@cleanup) { 132e1051a39Sopenharmony_ci unlink $_; 133e1051a39Sopenharmony_ci} 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ciif ($badtest) { 136e1051a39Sopenharmony_ci print "\n$badtest TESTS FAILED!!\n"; 137e1051a39Sopenharmony_ci} 138e1051a39Sopenharmony_cielse { 139e1051a39Sopenharmony_ci print "\n***All tests successful***\n"; 140e1051a39Sopenharmony_ci} 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_cisub write_pem { 143e1051a39Sopenharmony_ci my ( $filename, $str, $data ) = @_; 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci $filename =~ s/\.[^.]*$/.pem/; 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci push @cleanup, $filename; 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci open OUT, ">$filename"; 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ci print OUT "-----BEGIN $str-----\n"; 152e1051a39Sopenharmony_ci print OUT $data; 153e1051a39Sopenharmony_ci print OUT "-----END $str-----\n"; 154e1051a39Sopenharmony_ci 155e1051a39Sopenharmony_ci close OUT; 156e1051a39Sopenharmony_ci} 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_cisub run_reencode_test { 159e1051a39Sopenharmony_ci my ( $cmsdir, $tfile ) = @_; 160e1051a39Sopenharmony_ci unlink "tmp.der"; 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ci system( "$cmscmd -cmsout -inform DER -outform DER" 163e1051a39Sopenharmony_ci . " -in $cmsdir/$tfile -out tmp.der" ); 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci if ($?) { 166e1051a39Sopenharmony_ci print "\tReencode command FAILED!!\n"; 167e1051a39Sopenharmony_ci $badtest++; 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) { 170e1051a39Sopenharmony_ci print "\tReencode FAILED!!\n"; 171e1051a39Sopenharmony_ci $badtest++; 172e1051a39Sopenharmony_ci } 173e1051a39Sopenharmony_ci else { 174e1051a39Sopenharmony_ci print "\tReencode passed\n" if $verbose; 175e1051a39Sopenharmony_ci } 176e1051a39Sopenharmony_ci} 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_cisub run_certsout_test { 179e1051a39Sopenharmony_ci my ( $cmsdir, $tfile ) = @_; 180e1051a39Sopenharmony_ci unlink "tmp.der"; 181e1051a39Sopenharmony_ci unlink "tmp.pem"; 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ci system( "$cmscmd -cmsout -inform DER -certsout tmp.pem" 184e1051a39Sopenharmony_ci . " -in $cmsdir/$tfile -out tmp.der" ); 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci if ($?) { 187e1051a39Sopenharmony_ci print "\tCertificate output command FAILED!!\n"; 188e1051a39Sopenharmony_ci $badtest++; 189e1051a39Sopenharmony_ci } 190e1051a39Sopenharmony_ci else { 191e1051a39Sopenharmony_ci print "\tCertificate output passed\n" if $verbose; 192e1051a39Sopenharmony_ci } 193e1051a39Sopenharmony_ci} 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_cisub run_dataout_test { 196e1051a39Sopenharmony_ci my ( $cmsdir, $tfile ) = @_; 197e1051a39Sopenharmony_ci unlink "tmp.txt"; 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci system( 200e1051a39Sopenharmony_ci "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" ); 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci if ($?) { 203e1051a39Sopenharmony_ci print "\tDataout command FAILED!!\n"; 204e1051a39Sopenharmony_ci $badtest++; 205e1051a39Sopenharmony_ci } 206e1051a39Sopenharmony_ci elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) { 207e1051a39Sopenharmony_ci print "\tDataout compare FAILED!!\n"; 208e1051a39Sopenharmony_ci $badtest++; 209e1051a39Sopenharmony_ci } 210e1051a39Sopenharmony_ci else { 211e1051a39Sopenharmony_ci print "\tDataout passed\n" if $verbose; 212e1051a39Sopenharmony_ci } 213e1051a39Sopenharmony_ci} 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_cisub run_verify_test { 216e1051a39Sopenharmony_ci my ( $cmsdir, $tlist, $tfile ) = @_; 217e1051a39Sopenharmony_ci unlink "tmp.txt"; 218e1051a39Sopenharmony_ci 219e1051a39Sopenharmony_ci $form = "DER" if $tlist =~ /verifyder/; 220e1051a39Sopenharmony_ci $form = "SMIME" if $tlist =~ /verifymime/; 221e1051a39Sopenharmony_ci $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/; 222e1051a39Sopenharmony_ci $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/; 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci $cmd = 225e1051a39Sopenharmony_ci "$cmscmd -verify -inform $form" 226e1051a39Sopenharmony_ci . " -CAfile $cafile" 227e1051a39Sopenharmony_ci . " -in $cmsdir/$tfile -out tmp.txt"; 228e1051a39Sopenharmony_ci 229e1051a39Sopenharmony_ci $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/; 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ci system("$cmd 2>cms.err 1>cms.out"); 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_ci if ($?) { 234e1051a39Sopenharmony_ci print "\tVerify command FAILED!!\n"; 235e1051a39Sopenharmony_ci $badtest++; 236e1051a39Sopenharmony_ci } 237e1051a39Sopenharmony_ci elsif ( $tlist =~ /cont/ 238e1051a39Sopenharmony_ci && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 239e1051a39Sopenharmony_ci { 240e1051a39Sopenharmony_ci print "\tVerify content compare FAILED!!\n"; 241e1051a39Sopenharmony_ci $badtest++; 242e1051a39Sopenharmony_ci } 243e1051a39Sopenharmony_ci else { 244e1051a39Sopenharmony_ci print "\tVerify passed\n" if $verbose; 245e1051a39Sopenharmony_ci } 246e1051a39Sopenharmony_ci} 247e1051a39Sopenharmony_ci 248e1051a39Sopenharmony_cisub run_envelope_test { 249e1051a39Sopenharmony_ci my ( $cmsdir, $tlist, $tfile ) = @_; 250e1051a39Sopenharmony_ci unlink "tmp.txt"; 251e1051a39Sopenharmony_ci 252e1051a39Sopenharmony_ci $form = "DER" if $tlist =~ /envelopeder/; 253e1051a39Sopenharmony_ci $form = "SMIME" if $tlist =~ /envelopemime/; 254e1051a39Sopenharmony_ci 255e1051a39Sopenharmony_ci $cmd = 256e1051a39Sopenharmony_ci "$cmscmd -decrypt -inform $form" 257e1051a39Sopenharmony_ci . " -recip $cmsdir/BobRSASignByCarl.pem" 258e1051a39Sopenharmony_ci . " -inkey $cmsdir/BobPrivRSAEncrypt.pem" 259e1051a39Sopenharmony_ci . " -in $cmsdir/$tfile -out tmp.txt"; 260e1051a39Sopenharmony_ci 261e1051a39Sopenharmony_ci system("$cmd 2>cms.err 1>cms.out"); 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ci if ($?) { 264e1051a39Sopenharmony_ci print "\tDecrypt command FAILED!!\n"; 265e1051a39Sopenharmony_ci $badtest++; 266e1051a39Sopenharmony_ci } 267e1051a39Sopenharmony_ci elsif ( $tlist =~ /cont/ 268e1051a39Sopenharmony_ci && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 269e1051a39Sopenharmony_ci { 270e1051a39Sopenharmony_ci print "\tDecrypt content compare FAILED!!\n"; 271e1051a39Sopenharmony_ci $badtest++; 272e1051a39Sopenharmony_ci } 273e1051a39Sopenharmony_ci else { 274e1051a39Sopenharmony_ci print "\tDecrypt passed\n" if $verbose; 275e1051a39Sopenharmony_ci } 276e1051a39Sopenharmony_ci} 277e1051a39Sopenharmony_ci 278e1051a39Sopenharmony_cisub run_digest_test { 279e1051a39Sopenharmony_ci my ( $cmsdir, $tlist, $tfile ) = @_; 280e1051a39Sopenharmony_ci unlink "tmp.txt"; 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci my $cmd = 283e1051a39Sopenharmony_ci "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt"; 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_ci system("$cmd 2>cms.err 1>cms.out"); 286e1051a39Sopenharmony_ci 287e1051a39Sopenharmony_ci if ($?) { 288e1051a39Sopenharmony_ci print "\tDigest verify command FAILED!!\n"; 289e1051a39Sopenharmony_ci $badtest++; 290e1051a39Sopenharmony_ci } 291e1051a39Sopenharmony_ci elsif ( $tlist =~ /cont/ 292e1051a39Sopenharmony_ci && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 293e1051a39Sopenharmony_ci { 294e1051a39Sopenharmony_ci print "\tDigest verify content compare FAILED!!\n"; 295e1051a39Sopenharmony_ci $badtest++; 296e1051a39Sopenharmony_ci } 297e1051a39Sopenharmony_ci else { 298e1051a39Sopenharmony_ci print "\tDigest verify passed\n" if $verbose; 299e1051a39Sopenharmony_ci } 300e1051a39Sopenharmony_ci} 301e1051a39Sopenharmony_ci 302e1051a39Sopenharmony_cisub run_encrypted_test { 303e1051a39Sopenharmony_ci my ( $cmsdir, $tlist, $tfile, $key ) = @_; 304e1051a39Sopenharmony_ci unlink "tmp.txt"; 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ci system( "$cmscmd -EncryptedData_decrypt -inform DER" 307e1051a39Sopenharmony_ci . " -secretkey $key" 308e1051a39Sopenharmony_ci . " -in $cmsdir/$tfile -out tmp.txt" ); 309e1051a39Sopenharmony_ci 310e1051a39Sopenharmony_ci if ($?) { 311e1051a39Sopenharmony_ci print "\tEncrypted Data command FAILED!!\n"; 312e1051a39Sopenharmony_ci $badtest++; 313e1051a39Sopenharmony_ci } 314e1051a39Sopenharmony_ci elsif ( $tlist =~ /cont/ 315e1051a39Sopenharmony_ci && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 316e1051a39Sopenharmony_ci { 317e1051a39Sopenharmony_ci print "\tEncrypted Data content compare FAILED!!\n"; 318e1051a39Sopenharmony_ci $badtest++; 319e1051a39Sopenharmony_ci } 320e1051a39Sopenharmony_ci else { 321e1051a39Sopenharmony_ci print "\tEncryptedData verify passed\n" if $verbose; 322e1051a39Sopenharmony_ci } 323e1051a39Sopenharmony_ci} 324e1051a39Sopenharmony_ci 325e1051a39Sopenharmony_cisub cmp_files { 326e1051a39Sopenharmony_ci my ( $f1, $f2 ) = @_; 327e1051a39Sopenharmony_ci my ( $fp1, $fp2 ); 328e1051a39Sopenharmony_ci 329e1051a39Sopenharmony_ci my ( $rd1, $rd2 ); 330e1051a39Sopenharmony_ci 331e1051a39Sopenharmony_ci if ( !open( $fp1, "<$f1" ) ) { 332e1051a39Sopenharmony_ci print STDERR "Can't Open file $f1\n"; 333e1051a39Sopenharmony_ci return 0; 334e1051a39Sopenharmony_ci } 335e1051a39Sopenharmony_ci 336e1051a39Sopenharmony_ci if ( !open( $fp2, "<$f2" ) ) { 337e1051a39Sopenharmony_ci print STDERR "Can't Open file $f2\n"; 338e1051a39Sopenharmony_ci return 0; 339e1051a39Sopenharmony_ci } 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ci binmode $fp1; 342e1051a39Sopenharmony_ci binmode $fp2; 343e1051a39Sopenharmony_ci 344e1051a39Sopenharmony_ci my $ret = 0; 345e1051a39Sopenharmony_ci 346e1051a39Sopenharmony_ci for ( ; ; ) { 347e1051a39Sopenharmony_ci $n1 = sysread $fp1, $rd1, 4096; 348e1051a39Sopenharmony_ci $n2 = sysread $fp2, $rd2, 4096; 349e1051a39Sopenharmony_ci last if ( $n1 != $n2 ); 350e1051a39Sopenharmony_ci last if ( $rd1 ne $rd2 ); 351e1051a39Sopenharmony_ci 352e1051a39Sopenharmony_ci if ( $n1 == 0 ) { 353e1051a39Sopenharmony_ci $ret = 1; 354e1051a39Sopenharmony_ci last; 355e1051a39Sopenharmony_ci } 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ci } 358e1051a39Sopenharmony_ci 359e1051a39Sopenharmony_ci close $fp1; 360e1051a39Sopenharmony_ci close $fp2; 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ci return $ret; 363e1051a39Sopenharmony_ci 364e1051a39Sopenharmony_ci} 365e1051a39Sopenharmony_ci 366