Пример #1
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   S i g n a t u r e I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SignatureImage() computes a message digest from an image pixel stream with
%  an implementation of the NIST SHA-256 Message Digest algorithm.  This
%  signature uniquely identifies the image and is convenient for determining
%  if an image has been modified or whether two images are identical.
%
%  The format of the SignatureImage method is:
%
%      MagickBooleanType SignatureImage(Image *image,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType SignatureImage(Image *image,
  ExceptionInfo *exception)
{
  CacheView
    *image_view;

  char
    *hex_signature;

  double
    pixel;

  register const Quantum
    *p;

  SignatureInfo
    *signature_info;

  ssize_t
    y;

  StringInfo
    *signature;

  unsigned char
    *pixels;

  /*
    Compute image digital signature.
  */
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  signature_info=AcquireSignatureInfo();
  signature=AcquireStringInfo(image->columns*GetPixelChannels(image)*
    sizeof(pixel));
  image_view=AcquireVirtualCacheView(image,exception);
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    register ssize_t
      x;

    register unsigned char
      *q;

    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
    if (p == (const Quantum *) NULL)
      break;
    SetStringInfoLength(signature,image->columns*GetPixelChannels(image)*
      sizeof(pixel));
    pixels=GetStringInfoDatum(signature);
    q=pixels;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      register ssize_t
        i;

      if (GetPixelReadMask(image,p) == 0)
        {
          p+=GetPixelChannels(image);
          continue;
        }
      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
      {
        register ssize_t
          j;

        PixelChannel channel=GetPixelChannelChannel(image,i);
        PixelTrait traits=GetPixelChannelTraits(image,channel);
        if (traits == UndefinedPixelTrait)
          continue;
        pixel=QuantumScale*p[i];
        for (j=0; j < (ssize_t) sizeof(pixel); j++)
          *q++=(unsigned char) ((unsigned char *) &pixel)[j];
      }
      p+=GetPixelChannels(image);
    }
    SetStringInfoLength(signature,(size_t) (q-pixels));
    UpdateSignature(signature_info,signature);
  }
  image_view=DestroyCacheView(image_view);
  FinalizeSignature(signature_info);
  hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
  (void) DeleteImageProperty(image,"signature");
  (void) SetImageProperty(image,"signature",hex_signature,exception);
  /*
    Free resources.
  */
  hex_signature=DestroyString(hex_signature);
  signature=DestroyStringInfo(signature);
  signature_info=DestroySignatureInfo(signature_info);
  return(MagickTrue);
}
Пример #2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   S i g n a t u r e I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SignatureImage() computes a message digest from an image pixel stream with
%  an implementation of the NIST SHA-256 Message Digest algorithm.  This
%  signature uniquely identifies the image and is convenient for determining
%  if an image has been modified or whether two images are identical.
%
%  The format of the SignatureImage method is:
%
%      MagickBooleanType SignatureImage(Image *image)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
*/
MagickExport MagickBooleanType SignatureImage(Image *image)
{
  CacheView
    *image_view;

  char
    *hex_signature;

  ExceptionInfo
    *exception;

  QuantumInfo
    *quantum_info;

  QuantumType
    quantum_type;

  register const PixelPacket
    *p;

  SignatureInfo
    *signature_info;

  size_t
    length;

  ssize_t
    y;

  StringInfo
    *signature;

  unsigned char
    *pixels;

  /*
    Compute image digital signature.
  */
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
  if (quantum_info == (QuantumInfo *) NULL)
    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
      image->filename);
  quantum_type=RGBQuantum;
  if (image->matte != MagickFalse)
    quantum_type=RGBAQuantum;
  if (image->colorspace == CMYKColorspace)
    {
      quantum_type=CMYKQuantum;
      if (image->matte != MagickFalse)
        quantum_type=CMYKAQuantum;
    }
  signature_info=AcquireSignatureInfo();
  signature=AcquireStringInfo(quantum_info->extent);
  pixels=GetQuantumPixels(quantum_info);
  exception=(&image->exception);
  image_view=AcquireCacheView(image);
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
    if (p == (const PixelPacket *) NULL)
      break;
    length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
      pixels,&image->exception);
    SetStringInfoLength(signature,length);
    SetStringInfoDatum(signature,pixels);
    UpdateSignature(signature_info,signature);
  }
  image_view=DestroyCacheView(image_view);
  quantum_info=DestroyQuantumInfo(quantum_info);
  FinalizeSignature(signature_info);
  hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
  (void) DeleteImageProperty(image,"signature");
  (void) SetImageProperty(image,"signature",hex_signature);
  /*
    Free resources.
  */
  hex_signature=DestroyString(hex_signature);
  signature=DestroyStringInfo(signature);
  signature_info=DestroySignatureInfo(signature_info);
  return(MagickTrue);
}
Пример #3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I m p o r t K e y r i n g K e y                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ImportKeyringKey() imports a key to the keyring.
%
%  The format of the ImportKeyringKey method is:
%
%      WizardBooleanType ImportKeyringKey(KeyringInfo *keyring_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o keyring_info: The ring info.
%
%    o exception: Return any errors or warnings in this structure.
%
*/
WizardExport WizardBooleanType ImportKeyringKey(KeyringInfo *keyring_info,
  ExceptionInfo *exception)
{
  FileInfo
    *file_info;

  KeyringInfo
    *import_info;

  WizardStatusType
    status;

  size_t
    length;

  StringInfo
    *filetype,
    *magick;

  WizardOffsetType
    offset;

  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
  WizardAssert(KeymapDomain,keyring_info != (KeyringInfo *) NULL);
  WizardAssert(KeymapDomain,keyring_info->signature == WizardSignature);
  WizardAssert(KeymapDomain,exception != (ExceptionInfo *) NULL);
  import_info=AcquireKeyringInfo(keyring_info->path);
  SetKeyringId(import_info,keyring_info->id);
  if (ExportKeyringKey(import_info,exception) != WizardFalse)
    {
      char
        *id;

      /*
        Duplicate keys are not allowed in the keyring.
      */
      id=StringInfoToHexString(keyring_info->id);
      (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
        "unable to import key `%s' (its already in the keyring): %s",id,
        keyring_info->path);
      id=DestroyString(id);
      import_info=DestroyKeyringInfo(import_info);
      return(WizardFalse);
    }
  import_info=DestroyKeyringInfo(import_info);
  file_info=AcquireFileInfo(keyring_info->path,KeyringFilename,WriteFileMode,
    exception);
  if (file_info == (FileInfo *) NULL)
    return(WizardFalse);
  magick=GetWizardMagick(WizardMagick,sizeof(WizardMagick));
  status=WriteFileChunk(file_info,GetStringInfoDatum(magick),
    GetStringInfoLength(magick));
  magick=DestroyStringInfo(magick);
  filetype=GetWizardMagick((unsigned char *) KeyringFiletype,
    strlen(KeyringFiletype));
  status&=WriteFileChunk(file_info,GetStringInfoDatum(filetype),
    GetStringInfoLength(filetype));
  filetype=DestroyStringInfo(filetype);
  offset=lseek(GetFileDescriptor(file_info),0,SEEK_END);
  if (offset == -1)
    {
      file_info=DestroyFileInfo(file_info,exception);
      (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
        "unable to seek keyring `%s': %s",GetFilePath(file_info),
        strerror(errno));
      return(WizardFalse);
    }
  status&=WriteFile32Bits(file_info,keyring_info->signature);
  status&=WriteFile32Bits(file_info,0U);
  status&=WriteFile16Bits(file_info,keyring_info->protocol_major);
  status&=WriteFile16Bits(file_info,keyring_info->protocol_minor);
  status&=WriteFile64Bits(file_info,(WizardSizeType) keyring_info->timestamp);
  length=GetStringInfoLength(keyring_info->id);
  status&=WriteFile32Bits(file_info,(size_t) length);
  status&=WriteFileChunk(file_info,GetStringInfoDatum(keyring_info->id),length);
  length=GetStringInfoLength(keyring_info->key);
  status&=WriteFile32Bits(file_info,(size_t) length);
  status&=WriteFileChunk(file_info,GetStringInfoDatum(keyring_info->key),
    length);
  length=GetStringInfoLength(keyring_info->nonce);
  status&=WriteFile32Bits(file_info,(size_t) length);
  status&=WriteFileChunk(file_info,GetStringInfoDatum(keyring_info->nonce),
    length);
  if (status == WizardFalse)
    (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
      "unable to write keyring `%s': %s",GetFilePath(file_info),
      strerror(errno));
  file_info=DestroyFileInfo(file_info,exception);
  return(WizardTrue);
}
Пример #4
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   P r i n t K e y r i n g P r o p e r t i e s                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  PrintKeyringProperties() prints properties associated with each key in the
%  keyring.
%
%  The format of the PrintKeyringProperties method is:
%
%      WizardBooleanType PrintKeyringProperties(const char *path,
%        BlobInfo *keyring_blob,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o path: the keyring path.
%
%    o blob_ibfo: list the key properties to this blob.
%
%    o exception: Return any errors or warnings in this structure.
%
*/
WizardExport WizardBooleanType PrintKeyringProperties(const char *path,
  BlobInfo *keyring_blob,ExceptionInfo *exception)
{
  char
    *canonical_path,
    *hex,
    *keyring_rdf,
    message[WizardPathExtent];

  const struct stat
    *properties;

  FileInfo
    *file_info;

  KeyringInfo
    keyring_info;

  ssize_t
    count;

  StringInfo
    *filetype,
    *id,
    *key,
    *magick,
    *nonce,
    *target;

  size_t
    length;

  WizardSizeType
    timestamp;

  WizardStatusType
    status;

  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
  WizardAssert(KeymapDomain,exception != (ExceptionInfo *) NULL);
  file_info=AcquireFileInfo(path,KeyringFilename,ReadFileMode,exception);
  if (file_info == (FileInfo *) NULL)
    return(WizardTrue);
  keyring_rdf=AcquireString("  <keyring:Keyring rdf:about=\"");
  canonical_path=CanonicalXMLContent(GetFilePath(file_info),WizardFalse);
  (void) ConcatenateString(&keyring_rdf,canonical_path);
  (void) ConcatenateString(&keyring_rdf,"\">\n");
  properties=GetFileProperties(file_info);
  (void) ConcatenateString(&keyring_rdf,"    <keyring:modify-date>");
  (void) FormatWizardTime(properties->st_mtime,WizardPathExtent,message);
  (void) ConcatenateString(&keyring_rdf,message);
  (void) ConcatenateString(&keyring_rdf,"</keyring:modify-date>\n");
  (void) ConcatenateString(&keyring_rdf,"    <keyring:create-date>");
  (void) FormatWizardTime(properties->st_mtime,WizardPathExtent,message);
  (void) ConcatenateString(&keyring_rdf,message);
  (void) ConcatenateString(&keyring_rdf,"</keyring:create-date>\n");
  (void) ConcatenateString(&keyring_rdf,"    <keyring:timestamp>");
  (void) FormatWizardTime(time((time_t *) NULL),WizardPathExtent,message);
  (void) ConcatenateString(&keyring_rdf,message);
  (void) ConcatenateString(&keyring_rdf,"</keyring:timestamp>\n");
  (void) ConcatenateString(&keyring_rdf,"  </keyring:Keyring>\n");
  length=strlen(keyring_rdf);
  count=WriteBlob(keyring_blob,length,(unsigned char *) keyring_rdf);
  keyring_rdf=DestroyString(keyring_rdf);
  if (count != (ssize_t) length)
    ThrowFileException(exception,FileError,GetFilePath(file_info));
  magick=GetWizardMagick(WizardMagick,sizeof(WizardMagick));
  target=CloneStringInfo(magick);
  status=ReadFileChunk(file_info,GetStringInfoDatum(target),
    GetStringInfoLength(target));
  if ((status == WizardFalse) || (CompareStringInfo(target,magick) != 0))
    {
      file_info=DestroyFileInfo(file_info,exception);
      (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
        "corrupt key ring file `%s'",GetFilePath(file_info));
      return(WizardFalse);
    }
  magick=DestroyStringInfo(magick);
  target=DestroyStringInfo(target);
  filetype=GetWizardMagick((unsigned char *) KeyringFiletype,
    strlen(KeyringFiletype));
  target=CloneStringInfo(filetype);
  status&=ReadFileChunk(file_info,GetStringInfoDatum(target),
    GetStringInfoLength(target));
  if ((status == WizardFalse) || (CompareStringInfo(target,filetype) != 0))
    {
      file_info=DestroyFileInfo(file_info,exception);
      (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
        "corrupt key ring file `%s'",GetFilePath(file_info));
      return(WizardFalse);
    }
  filetype=DestroyStringInfo(filetype);
  target=DestroyStringInfo(target);
  length=0;
  (void) ResetWizardMemory(&keyring_info,0,sizeof(keyring_info));
  while (ReadFile32Bits(file_info,&keyring_info.signature) != 0)
  {
    if (keyring_info.signature != WizardSignature)
      {
        file_info=DestroyFileInfo(file_info,exception);
        (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
          "corrupt key ring file `%s'",GetFilePath(file_info));
        return(WizardFalse);
      }
    status&=ReadFile32Bits(file_info,&length);
    status&=ReadFile16Bits(file_info,&keyring_info.protocol_major);
    status&=ReadFile16Bits(file_info,&keyring_info.protocol_minor);
    if ((keyring_info.protocol_major == 1) &&
        (keyring_info.protocol_minor == 0))
      timestamp=(time_t) length;
    else
      status&=ReadFile64Bits(file_info,&timestamp);
    keyring_info.timestamp=(time_t) timestamp;
    status&=ReadFile32Bits(file_info,&length);
    if (status == WizardFalse)
      {
        file_info=DestroyFileInfo(file_info,exception);
        (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
          "corrupt key ring file `%s'",GetFilePath(file_info));
        return(WizardFalse);
      }
    id=AcquireStringInfo(length);
    status&=ReadFileChunk(file_info,GetStringInfoDatum(id),
      GetStringInfoLength(id));
    status&=ReadFile32Bits(file_info,&length);
    if (status == WizardFalse)
      {
        file_info=DestroyFileInfo(file_info,exception);
        (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
          "corrupt key ring file `%s'",GetFilePath(file_info));
        return(WizardFalse);
      }
    key=AcquireStringInfo(length);
    status&=ReadFileChunk(file_info,GetStringInfoDatum(key),
      GetStringInfoLength(key));
    status&=ReadFile32Bits(file_info,&length);
    if (status == WizardFalse)
      {
        file_info=DestroyFileInfo(file_info,exception);
        (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
          "corrupt key ring file `%s'",GetFilePath(file_info));
        return(WizardFalse);
      }
    nonce=AcquireStringInfo(length);
    status&=ReadFileChunk(file_info,GetStringInfoDatum(nonce),
      GetStringInfoLength(nonce));
    keyring_rdf=AcquireString("  <keyring:Key rdf:about=\"");
    hex=StringInfoToHexString(id);
    (void) ConcatenateString(&keyring_rdf,hex);
    hex=DestroyString(hex);
    (void) ConcatenateString(&keyring_rdf,"\">\n");
    (void) ConcatenateString(&keyring_rdf,"    <keyring:memberOf "
      "rdf:resource=\"");
    (void) ConcatenateString(&keyring_rdf,canonical_path);
    (void) ConcatenateString(&keyring_rdf,"\"/>\n");
    (void) ConcatenateString(&keyring_rdf,"    <keyring:nonce>");
    hex=StringInfoToHexString(nonce);
    (void) ConcatenateString(&keyring_rdf,hex);
    hex=DestroyString(hex);
    (void) ConcatenateString(&keyring_rdf,"</keyring:nonce>\n");
    (void) ConcatenateString(&keyring_rdf,"    <keyring:timestamp>");
    (void) FormatWizardTime(keyring_info.timestamp,WizardPathExtent,message);
    (void) ConcatenateString(&keyring_rdf,message);
    (void) ConcatenateString(&keyring_rdf,"</keyring:timestamp>\n");
    (void) ConcatenateString(&keyring_rdf,"    <keyring:protocol>");
    (void) FormatLocaleString(message,WizardPathExtent,"%u.%u",
      keyring_info.protocol_major,(unsigned int) keyring_info.protocol_minor);
    (void) ConcatenateString(&keyring_rdf,message);
    (void) ConcatenateString(&keyring_rdf,"</keyring:protocol>\n");
    (void) ConcatenateString(&keyring_rdf,"  </keyring:Key>\n");
    length=strlen(keyring_rdf);
    count=WriteBlob(keyring_blob,length,(unsigned char *) keyring_rdf);
    keyring_rdf=DestroyString(keyring_rdf);
    if (count != (ssize_t) length)
      ThrowFileException(exception,FileError,GetFilePath(file_info));
    nonce=DestroyStringInfo(nonce);
    key=DestroyStringInfo(key);
    id=DestroyStringInfo(id);
    if (status == WizardFalse)
      {
        file_info=DestroyFileInfo(file_info,exception);
        (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
          "corrupt key ring file `%s'",GetFilePath(file_info));
        return(WizardFalse);
      }
  }
  canonical_path=DestroyString(canonical_path);
  file_info=DestroyFileInfo(file_info,exception);
  return(WizardTrue);
}
Пример #5
0
WizardExport WizardBooleanType ExportKeyring(int argc,char **argv,
  ExceptionInfo *exception)
{
#define DestroyKeyring() \
{ \
  for (i=0; i < (ssize_t) argc; i++) \
    argv[i]=DestroyString(argv[i]); \
  argv=(char **) RelinquishWizardMemory(argv); \
}
#define ThrowKeyringException(asperity,tag,context) \
{ \
  (void) ThrowWizardException(exception,GetWizardModule(),asperity,tag, \
    context); \
  DestroyKeyring(); \
  return(WizardFalse); \
}
#define ThrowInvalidArgumentException(option,argument) \
{ \
  (void) ThrowWizardException(exception,GetWizardModule(),OptionError, \
    "invalid argument: `%s': %s",argument,option); \
  DestroyKeyring(); \
  return(WizardFalse); \
}

  const char
    *filename,
    *keyring,
    *option;

  KeyringInfo
    *keyring_info;

  register ssize_t
    i;

  StringInfo
    *id;

  WizardBooleanType
    status;

  /*
    Parse command-line options.
  */
  status=WizardFalse;
  keyring=(const char *) NULL;
  id=(StringInfo *) NULL;
  filename=argv[argc-1];
  for (i=1; i < (ssize_t) (argc-1); i++)
  {
    option=argv[i];
    if (IsWizardOption(option) != WizardFalse)
      switch (*(option+1))
      {
        case 'd':
        {
          if (LocaleCompare(option,"-debug") == 0)
            {
              LogEventType
                event_mask;

              i++;
              if (i == (ssize_t) argc)
                ThrowKeyringException(OptionError,"missing log event mask: "
                  "`%s'",option);
              event_mask=SetLogEventMask(argv[i]);
              if (event_mask == UndefinedEvents)
                ThrowKeyringException(OptionFatalError,"unrecognized log event "
                  "type: `%s'",argv[i]);
              break;
            }
          ThrowKeyringException(OptionFatalError,"unrecognized option: `%s'",
            option);
          break;
        }
        case 'e':
        {
          if (LocaleCompare("export",option+1) == 0)
            {
              if (*option == '+')
                break;
              i++;
              if (i == (ssize_t) argc)
                ThrowKeyringException(OptionError,"missing key id: `%s'",
                  option);
              id=HexStringToStringInfo(argv[i]);
              break;
            }
          ThrowKeyringException(OptionFatalError,"unrecognized option: `%s'",
            option);
          break;
        }
        case 'h':
        {
          if ((LocaleCompare("help",option+1) == 0) ||
              (LocaleCompare("-help",option+1) == 0))
            KeyringUsage();
          ThrowKeyringException(OptionFatalError,"unrecognized option: `%s'",
            option);
          break;
        }
        case 'l':
        {
          if (LocaleCompare(option,"-list") == 0)
            {
              ssize_t
                list;

              if (*option == '+')
                break;
              i++;
              if (i == (ssize_t) argc)
                ThrowKeyringException(OptionError,"missing list type: `%s'",
                  option);
              if (LocaleCompare(argv[i],"configure") == 0)
                {
                  (void) ListConfigureInfo((FILE *) NULL,exception);
                  Exit(0);
                }
              list=ParseWizardOption(WizardListOptions,WizardFalse,argv[i]);
              if (list < 0)
                ThrowKeyringException(OptionFatalError,"unrecognized list "
                  "type: `%s'",argv[i]);
              (void) ListWizardOptions((FILE *) NULL,(WizardOption) list,
                exception);
              Exit(0);
              break;
            }
          if (LocaleCompare("log",option+1) == 0)
            {
              if (*option == '+')
                break;
              i++;
              if ((i == (ssize_t) argc) ||
                  (strchr(argv[i],'%') == (char *) NULL))
                ThrowKeyringException(OptionFatalError,"missing argument: `%s'",
                  option);
              break;
            }
          ThrowKeyringException(OptionFatalError,"unrecognized option: `%s'",
            option);
          break;
        }
        case 'v':
        {
          if (LocaleCompare(option,"-version") == 0)
            {
              (void) fprintf(stdout,"Version: %s\n",GetWizardVersion(
                (size_t *) NULL));
              (void) fprintf(stdout,"Copyright: %s\n\n",GetWizardCopyright());
              exit(0);
            }
          ThrowKeyringException(OptionFatalError,"unrecognized option: `%s'",
            option);
          break;
        }
        default:
        {
          ThrowKeyringException(OptionFatalError,"unrecognized option: `%s'",
            option);
          break;
        }
      }
    /*
      Export key from keyring.
    */
    keyring_info=AcquireKeyringInfo(keyring);
    SetKeyringId(keyring_info,id);
    if (ExportKeyringKey(keyring_info,exception) == WizardFalse)
      {
        char
          *hex_id;

        hex_id=StringInfoToHexString(id);
        (void) ThrowWizardException(exception,GetWizardModule(),KeyringError,
          "no such key `%s': `%s'",hex_id,keyring);
        hex_id=DestroyString(hex_id);
      }
    else
      {
        SetKeyringPath(keyring_info,filename);
        status=ImportKeyringKey(keyring_info,exception);
      }
    id=DestroyStringInfo(id);
    keyring_info=DestroyKeyringInfo(keyring_info);
  }
  /*
    Free resources.
  */
  DestroyKeyring();
  return(status);
}