/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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,×tamp); 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); }
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); }